二、SwiftUI页面布局

57 阅读2分钟

1、Group多模拟器预览

import SwiftUI

struct ContentView : View {
    
    var body: some View {
        Group {
            Text("Apple")
            Text("Banana")
            Text("Orange")
            Text("Watermelon")
            Text("Grape")
            Text("Papaya")
            Text("Pear")
        }
        .font(.title)
        .foregroundColor(.orange)
    }
}

2、HStack -- 水平方向排列

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        HStack(alignment: .top, spacing: 40)
        {
            Image(systemName: "book.fill")
            Text("Interactive Tutorials")
            Spacer()
            Image(systemName: "icloud.and.arrow.down")
        }
        .padding()
    }
}

3、VStack -- 竖向排列

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        VStack(alignment: .leading, spacing: 50)
        {
            Text("The fruit and the tree")
                .font(.largeTitle)
            
            Image("Apple")
            
            Text("An apple is a sweet, edible fruit produced by an apple tree Apple trees are cultivated worldwide and are the most widely grown species in the genus Malus.")
        }
        .padding()
    }
}

4、ZStack -- 垂直屏幕方向排列

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        ZStack(alignment: .center)
        {
            Image("beach")
                .clipShape(Circle())
            
            Text("Sea beach")
                .font(.system(size: 48))
                .foregroundColor(.white)
            
            Text("Hawaii - USA")
                .font(.system(size: 18))
                .foregroundColor(.white)
                .offset(x: 0, y: 36)
        }
    }
}

5、惰性加载竖向堆栈 -- LazyVStack

VStack 和 HStack会预先加载内容,LazyVStack 和 LazyHStack 仅当滚动到视图时才显示内容。

image.png

import SwiftUI

struct MyCell : View
{
    var cellIndex : Int
    
    init(cellIndex : Int)
    {
        self.cellIndex = cellIndex
        print("cell \(cellIndex) initialized.")
    }
    
    var body : some View
    {
        Text("Interactive tutorial #\(cellIndex)")
    }
}

struct HeaderView : View
{
    var body: some View
    {
        Text("Header View")
            .padding()
            .foregroundColor(Color.white)
            .frame(maxWidth: .infinity)
            .background(Color.orange)
    }
}

struct ContentView : View
{
    var body: some View
    {
        ScrollView
        {
            LazyVStack(alignment: .leading, spacing: 20, pinnedViews: [.sectionHeaders], content:
            {
                Section(header: HeaderView())
                {
                    ForEach(1...40, id: \.self)
                    { count in
                        MyCell(cellIndex: count)
                    }
                }
            })
        }
        .padding()
    }
}

6、网格布局 -- LazyVGrid & LazyHGrid

image.png

//
//  Created by LiFazhan
//  Copyright © www.hdjc8.com
//

import SwiftUI

struct ContentView : View
{
    var items : [GridItem] = [
        GridItem(GridItem.Size.flexible(), spacing: 10),
        
        GridItem(GridItem.Size.fixed(160), spacing: 10),
        
        GridItem(GridItem.Size.flexible(), spacing: 10)
    ]
    
    var body: some View
    {
        ScrollView
        {
            LazyVGrid(columns: items, content:
            {
                ForEach(1 ... 10, id: \.self)
                { index in
                    Image("Avarta-\(index)")
                        .resizable()
                        .frame(height: 100)
                }
            })
        }
        .padding()
    }
}

7、分隔线 -- Divider

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        VStack
        {
            Image(systemName: "clock")
                .font(.system(size: 36))
            
            Divider()
                .background(Color.purple)
                .scaleEffect(CGSize(width: 1, height: 20))
                .padding(Edge.Set.init(arrayLiteral: .top, .bottom), 20)
            
            Text("\(Date())")
        }
    }
}

8、Spacer空格视图

Spacer在HStack中撑满水平空间,在VStack中撑满竖向空间。

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        VStack
        {
            HStack
            {
                Spacer()
                Image(systemName: "clock")
            }
            
            HStack
            {
                Image(systemName: "clock")
                Spacer()
                    .frame(width: 20)
                Text("\(Date())")
            }
        }
        .padding()
    }
}

9、List列表

image.png

import SwiftUI

struct ContentView : View
{
    @State var languages = ["Objective-C", "Swift", "Flutter"]
    
    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach(languages, id:\.self)
                { language in
                    Text(language)
                }
                .onInsert(of: ["demo"], perform:
                { (offset, message) in
                    print(offset)
                })
            }
            .navigationBarTitle(Text("Edit Row"), displayMode: .large)
            .navigationBarItems(trailing: Button(action: addItem, label: {
                Text("Add")
            }))
        }
    }
    
    func addItem()
    {
        languages.append("C++")
    }
}

10、List编辑功能实现

image.png

import SwiftUI

struct ContentView : View {

    @State var languages = ["Objective-C", "Swift", "Flutter"]

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach(languages,id: \.self)
                { language in
                    Text(language)
                }
                .onDelete(perform: delete)
            }
            .navigationBarItems(trailing: EditButton())
        }
    }
    
    func delete(at offsets: IndexSet)
    {
        if let first = offsets.first
        {
            languages.remove(at: first)
        }
    }
}

11、List拖拽调序

image.png

import SwiftUI

struct ContentView : View
{
    @State var languages = ["Objective-C", "Swift", "Flutter"]

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach(languages,id: \.self)
                { language in
                    Text(language)
                }
                .onMove
                { (source, destination) in
                    self.languages.move(fromOffsets: source, toOffset: destination)
                }
            }
            .navigationBarTitle(Text("Edit Row"), displayMode: .large)
            .navigationBarItems(trailing: EditButton())
        }
    }
}

12、Section的使用

image.png

import SwiftUI

struct ContentView : View
{
    var body: some View
    {
        List
        {
            Section(header: Text("Fruit"),
                    footer: Text("Total: 3"))
            {
                Text("Apple")
                Text("Banana")
                Text("Pear")
            }
            
            Section(header: Text("Animals"),
                    footer: Text("Total: 4"))
            {
                Text("Tiger")
                Text("Lion")
                Text("Monkey")
                Text("Rabbit")
            }
        }
    }
}

13、ScrollView在限定的区域内显示超长内容

image.png

import SwiftUI

struct ContentView : View
{
    let scrollView : some View = ScrollView(.vertical, showsIndicators: false)
    {
        VStack(alignment: HorizontalAlignment.leading, spacing: 20)
        {
            Text("Overview")
                .font(.system(size: 48))
                .padding(10)
            
            Image("iPhone")
                .resizable()
                .frame(width: 300, height: 556, alignment: .center)
        }
    }
    var body: some View
    {
        scrollView
            .background(Color.orange)
            .padding(10)
            .onAppear {
                print("-----")
                print(scrollView.body)
            }
    }
}