SwiftUIEKtensions

目录

扩展

TextField("Input", text: $text, axis: .vertical)
    .textFieldStyle(.roundedBorder)
    .readSize {
        print("size: \($0)")
    }

键盘相关修饰符 (仅限 iOS)

AwesomeView()
    .onKeyboardAppear { heigth in }

基于平台的修饰符

AwesomeView()
    .modifier(for: .iOS, { $0.background(Color.gray) })
    .modifier(for: .macOS, { $0.background(Color.green)}
    .tvOSOnlyModifier { $0.background(Color.blue) }
    .watchOSOnlyModifier { $0.background(Color.red) }

视图

图像选择器

请勿忘记添加所需的隐私权限。

struct ImagePickerExampleView: View {

    @State var showImagePicker: Bool = false
    @State var image: UIImage?

    var body: some View {
        VStack {
            if let image = image {
                Image(uiImage: image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
            }
            Button("Pick image") {
                self.showImagePicker.toggle()
            }
        }
        .sheet(isPresented: $showImagePicker) {
            ImagePickerView(sourceType: .photoLibrary) { image in
                self.image = image
            }
        }
    }
}

邮件

import MessagesUI
import SwiftUI

@State private var result: Result<MFMailComposeResult, Error>? = nil
@State private var isShowingMailView = false

var body: some View {
    Form {
        Button(action: {
            if MFMailComposeViewController.canSendMail() {
                self.isShowingMailView.toggle()
            } else {
                print("Can't send emails from this device")
            }
            if result != nil {
                print("Result: \(String(describing: result))")
            }
        }) {
            HStack {
                Image(systemName: "envelope")
                Text("Contact Us")
            }
        }
        // .disabled(!MFMailComposeViewController.canSendMail())
    }
    .sheet(isPresented: $isShowingMailView) {
        MailView(result: $result) { composer in
            composer.setSubject("Secret")
            composer.setToRecipients(["eneskaraosman53@gmail.com"])
        }
    }
}

懒加载视图

NavigationView {
    NavigationLink(destination: LazyView(Text("My details page")) {
        Text("Go to details")
    }
}

无状态单选列表

一次选择 1 个项目并将其绑定到 selectedItem 变量。

StatelessSingleSelectionList<Item: Identifiable, Content: View, Modifier: ViewModifier>(
    
    // Data source
    items: [Item],
    
    // To keep track of selected item
    selectedItem: Binding<Item?>,
    
    // Built in: CheckmarkModifier or create custom one
    modifier: @escaping () -> Modifier,
    
    // Your List row content
    rowContent: @escaping (Item) -> Content
)

结果类似如下;

=========================
= Item - 1              =
=========================
=========================
= Item - 2           ✅ =
=========================
=========================
= Item - 3              =
=========================

有状态单选列表

一次选择 1 个项目并更改 SelectableItem 的 isSelected 属性

protocol SelectableItem: Identifiable { 
    var isSelected: Bool { get set }
}

StatefulSingleSelectionList<Item: SelectableItem, Content: View, Modifier: ViewModifier>(
    
    // Data source
    items: [Item],
    
    // Built in: CheckmarkModifier or create custom one
    modifier: @escaping () -> Modifier,
    
    // Your List row content
    rowContent: @escaping (Item) -> Content
)

无状态多选列表

允许一次选择多个项目并将其绑定到 selectedItems 变量。

StatelessMultipleSelectionList<Item: Identifiable, Content: View, Modifier: ViewModifier>(
    
    // Data source
    items: [Item],
    
    // To keep track of selected item
    selectedItems: Binding<[Item]>,
    
    // Built in: CheckmarkModifier or create custom one
    modifier: @escaping () -> Modifier,
    
    // Your List row content
    rowContent: @escaping (Item) -> Content
)

结果类似如下;

=========================
= Item - 1              =
=========================
=========================
= Item - 2           ✅ =
=========================
=========================
= Item - 3           ✅ =
=========================

有状态多选列表

允许选择多个项目并更改相关 SelectableItem 的 isSelected 属性

protocol SelectableItem: Identifiable { 
    var isSelected: Bool { get set }
}

StatefulMultipleSelectionList<Item: SelectableItem, Content: View, Modifier: ViewModifier>(
    
    // Data source
    items: [Item],
    
    // Built in: CheckmarkModifier or create custom one
    modifier: @escaping () -> Modifier,
    
    // Your List row content
    rowContent: @escaping (Item) -> Content
)

基于设备方向的视图

设备方向自适应视图

确保将 DeviceOrientationInfo 对象作为 EnvironmentObject 传递,然后您可以使用;

DeviceOrientationBasedView(
    portrait: {
        // some `View`
    },
    landscape: {
        // some `View`
    }
)

视图修饰符