Nic*_*hrn 7 uiimagepickercontroller swiftui
我UIImagePickerController
通过在修改器内部提供逻辑来在我的应用程序中呈现 a sheet
。简而言之,以下三种类型处理显示和消除UIImagePickerController
类型内部的实例UIViewControllerRepresentable
,其按预期工作:
struct DetailsView: View {
enum Sheet: Hashable, Identifiable {
case takePhoto
var id: Int { hashValue }
}
@State private var activeSheet: Sheet?
var body: some View {
Text("Hello, World!")
.sheet(item: $activeSheet) { (sheet) in self.view(for: sheet) }
}
private func view(for sheet: Sheet) -> some View {
switch sheet {
case .takePhoto: return PhotoSelectionView(showImagePicker: .init(get: { sheet == .takePhoto }, set: { (show) in self.activeSheet = show ? .takePhoto : nil }), image: $selectedImage, photoSource: .camera).edgesIgnoringSafeArea(.all)
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct ImagePicker: UIViewControllerRepresentable {
@Binding var isShown: Bool
@Binding var image: Image?
let photoSource: PhotoSource
func makeCoordinator() -> ImagePickerCoordinator {
return ImagePickerCoordinator(isShown: $isShown, selectedImage: $image)
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
if photoSource == .camera, UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
imagePicker.cameraCaptureMode = .photo
}
imagePicker.delegate = context.coordinator
return imagePicker
}
}
Run Code Online (Sandbox Code Playgroud)
class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@Binding private var isShown: Bool
@Binding private var selectedImage: Image?
init(isShown: Binding<Bool>, selectedImage: Binding<Image?>) {
_isShown = isShown
_selectedImage = selectedImage
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// handle photo selection
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss()
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是相机视图是模态呈现的,它没有覆盖整个屏幕。当相机作为源时,这会导致UIImagePickerController
布局有时看起来会被破坏,就好像相机不是为了以这种方式呈现一样。设置imagePicker.modalPresentationStyle = .fullScreen
不会导致全屏演示。
如何以全屏布局显示相机,使其不出现卡片式的呈现方式?
ada*_*086 16
结合@LaX 和@GrandSteph 的答案,我有:
.fullScreenCover(isPresented: $activeSheet, content: {
ImagePicker(image: $inputImage, sourceType: .camera)
.edgesIgnoringSafeArea(.all)
})
Run Code Online (Sandbox Code Playgroud)
好吧,对这个答案持保留态度。我可能会因此而被投下地狱……但苹果也应该如此,因为它没有提供一种在 SwiftUI 中全屏显示 UIImagePickerController 的简单方法。
非常糟糕的技巧是在 rootView 中创建选择器并让它忽略安全区域。然后将所有必要的参数作为绑定传递到需要 imagePicker 的视图
struct mainView: View {
@State private var imagePicked = UIImage()
@State private var showImagePicker = false
@State private var pickerSource = UIImagePickerController.SourceType.camera
var body: some View {
ZStack {
AvatarView(showImagePicker: self.$showImagePicker, pickerSource: self.$pickerSource , imagePicked: self.$imagePicked)
if self.showImagePicker {
ImagePickerView(isPresented: self.$showImagePicker, selectedImage: self.$imagePicked, source: .camera).edgesIgnoringSafeArea(.all)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您的 Avatar 视图将包含更新这些绑定所需的所有代码。像这样的东西
HStack () {
Button(action: {
self.showActionSheet.toggle()
}) {
MyImageView(image: self.imagePicked)
}
.actionSheet(isPresented: $showActionSheet, content: {
ActionSheet(title: Text("Picture source"), buttons: [
.default(Text("Camera"), action: {
self.pickerSource = .camera
self.showImagePicker.toggle()
}),
.default(Text("Photo Library"), action: {
self.pickerSource = .photoLibrary
self.showImagePicker.toggle()
}),
.destructive(Text("Cancel"))
])
})
}
Run Code Online (Sandbox Code Playgroud)
老实说,我对是否提供这个解决方案犹豫不决,这段代码让我眼睛流血,但我认为有人在阅读本文时可能有更好的想法,并提供一种真正干净的 SwiftUI 方式来实现它。
这个解决方案的好处是它可以很好地管理方向的变化,让我们面对现实吧,UIImagePickerController 无法正确适应纸张。对于照片库来说还可以,但对于相机来说就不行了。
归档时间: |
|
查看次数: |
4235 次 |
最近记录: |