Sunday, December 4, 2022
HomeiOS Developmentios - Open pop-up window inside Mannequin window no errors сrash after...

ios – Open pop-up window inside Mannequin window no errors сrash after compiling


The house web page permits you to open a mannequin window by which there are fields for knowledge, on the similar time I attempt to make a button in the identical mannequin window that opens a pop-up window with which you’ll choose a number of photographs, after confirming the pop-up window closes and the chosen photographs seem within the mode slide underneath fields, like I mentioned no errors in code, after compiling I can see House web page, however when I attempt to open this mannequin window (the place all fields and popup) it is crashes with error:

Tried to scroll the gathering view to an out-of-bounds merchandise (0) when there are solely 0 objects in part 0. Assortment view: and many various phrases and meanings which might be unlikely to assist as a result of there isn’t any finish to them and naturally there may be nothing on Google about this both

I attempted as a lot as doable to take away the additional code, which is under no circumstances associated to the issue for readability.

That is how my mannequin window seems to be like (there aren’t any cancel and save buttons on the toolBar, however within the code they exist already and work) -the screenshot was taken when this mannequin window was nonetheless open

AddItemsView


import SwiftUI
import FirebaseAuth
import Firebase
import FirebaseFirestore
import Photographs
import FirebaseStorage

enum Mode {
  case new
  case edit
}

enum Motion {
  case delete
  case carried out
  case cancel
}

struct AddItemView: View {
@Atmosphere(.presentationMode) personal var presentationMode
@State var presentActionSheet = false

@State var showPicker: Bool = false
@State var pickedImages: [UIImage] = []
    
// MARK: - State (Initialiser-modifiable)

@ObservedObject var viewModel = NewItemView()
var mode: Mode = .new
var completionHandler: ((Consequence<Motion, Error>) -> Void)?

// MARK: - UI Parts

var cancelButton: some View {
  Button(motion: { self.handleCancelTapped() }) { 
    Textual content("Cancel")
  }
}

var saveButton: some View {
  Button(motion: { self.handleDoneTapped() }) {
    Textual content(mode == .new ? "Carried out" : "Save")
  }
  .disabled(!viewModel.modified)
}
    
var physique: some View {
    NavigationView {.        // right here begins all textfields of the shape
        Type {
            Part(header: Textual content("New Merchandise")) {
                TextField("Title", textual content: $viewModel.singleitem.title)
                TextField("Description", textual content: $viewModel.singleitem.description)
            }
            
            Part(header: Textual content("Writer")) {
                TextField("Writer", textual content: $viewModel.singleitem.writer)
            }
            
            if mode == .edit {
                Part {
                    Button("Delete merchandise") { self.presentActionSheet.toggle() }
                        .foregroundColor(.purple)
                }
            }
            Part(footer:   // right here begin tabview the place exhibits popup, additionally I take advantage of part: footer, bc with out that every one stuff for popup exhibits inside type discipline 

                
                TabView {
                    
                    ForEach(pickedImages, id: .self) { picture in
                        
                        GeometryReader { proxy in
                            
                            let dimension = proxy.dimension
                            Picture(uiImage: picture)
                            
                        }
                        .padding()
                    }
                    
                }
                .body(top: 450)
                // MARK: Swift UI Bug
                
                .tabViewStyle(.web page(indexDisplayMode: pickedImages.isEmpty ? .by no means :  .all the time))
                .toolbar {
                    Button {
                        
                        showPicker.toggle()
                        
                    } label: {
                        
                        Picture(systemName: "plus") // I did plus button for toolBar however have already got Save button (its not an issue)
                        
                    }
                }
            
            .popupImagePicker(present: $showPicker) { asset in    // slide mode after accepting chosen photographs
                
                // MARK: Instance
                let supervisor = PHCachingImageManager.default()
                let choices = PHImageRequestOptions()
                choices.isSynchronous = true
                
                DispatchQueue.international(qos: .userInitiated).async {
                    asset.forEach { asset in
                        
                        supervisor.requestImage(for: asset, targetSize: .init(), contentMode: .default, choices: choices) { picture, _ in
                            
                            guard let picture = picture else { return }
                         
                            DispatchQueue.primary.async {
                                
                                self.pickedImages.append(picture)
                                
                            }
                            
                        }
                        
                    }
                }
                
            }

            ) {
                EmptyView()
            }
         }
        .navigationBarItems(main: cancelButton, trailing: saveButton)
        
        
        
    }
    
    
      // MARK: Grid Picture Content material

      
    .navigationTitle(mode == .new ? "Merchandise" : viewModel.singleitem.title)
    .navigationBarTitleDisplayMode(mode == .new ? .inline : .massive)
    .navigationBarItems( // these buttons I already I mentioned
      main: cancelButton,
      trailing: saveButton
    )
    .actionSheet(isPresented: $presentActionSheet) {
      ActionSheet(title: Textual content("Are you positive?"),
                  buttons: [
                    .destructive(Text("Delete item"),
                                 action: { self.handleDeleteTapped() }),
                    .cancel()
                  ])
    }
      
  
    
}

// MARK: - Motion Handlers

func handleCancelTapped() {
  self.dismiss()
}

func handleDoneTapped() {
  self.viewModel.handleDoneTapped()
  self.dismiss()
}

func handleDeleteTapped() {
  viewModel.handleDeleteTapped()
  self.dismiss()
  self.completionHandler?(.success(.delete))
}

func dismiss() {
  self.presentationMode.wrappedValue.dismiss()
}
    
}

struct AddItemView_Previews: PreviewProvider {
  static var previews: some View {
      AddItemView()

  }
}

extension View {
  func endTextEditing() {
    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder),
                                    to: nil, from: nil, for: nil)
  }
}

PhotosView

import SwiftUI
import Photographs 

struct PhotosView: View {. // right here truly what we see (popup) inside AddItemView after pressed button "plus"
    
    // MARK: Connecting image-picker View Mannequin
    @StateObject var imagePickerModel: ImagePickerViewModel = .init()
    @Atmosphere(.self) var env
    // MARK: Callbacks
    var onEnd: ()->()
    var onSelect: ([PHAsset])->()
    
    var physique: some View {
        let deviceSize = UIScreen.primary.bounds.dimension
        VStack(spacing: 0) {
            
            HStack {
                
                Textual content("Choose Picture")

                Button {
                            onEnd()
                } label: {
                    Picture(systemName: "xmark.circle.fill")

                }
                
                
            }
            .padding([.horizontal, .top])
            .padding(.backside, 10)
            
            ScrollView(.vertical, showsIndicators: false) {
                
                LazyVGrid(columns: Array(repeating: GridItem(.versatile(), spacing: 10), rely: 4),
                          spacing: 12) {
                    
                    ForEach($imagePickerModel.fetchedImages){$imageAsset
                        
                        in
                        // MARK: Grid Content material
                        GridContent(imageAsset: imageAsset)
                            .onAppear {
                                
                                if imageAsset.thumbnail == nil {
                                    
                                    // MARK: Fetching thumbnail picture
                                    let supervisor = PHCachingImageManager.default()
                                    supervisor.requestImage(for: imageAsset.asset, targetSize: CGSize(width: 100, top: 100), contentMode: .aspectFill, choices: nil) { picture,
                                        
                                        _ in
                                        imageAsset.thumbnail = picture
                                        
                                    }
                                }
                                
                            }
                        
                    }
                    
                }
               .padding()
            }
            .safeAreaInset(edge: .backside) {
                
                // MARK: Add button
                Button {
                    
                    let imageAssets = imagePickerModel.selectedImages.compactMap {
                        
                        imageAsset -> PHAsset? in
                        return imageAsset.asset
                        
                    }
                    onSelect(imageAssets)
                } label: {
                    Textual content("Add(imagePickerModel.selectedImages.isEmpty ? "" : "(imagePickerModel.selectedImages.rely)Photographs")")
                }
                .disabled(imagePickerModel.selectedImages.isEmpty)
                .opacity(imagePickerModel.selectedImages.isEmpty ? 0.6 : 1)
                .padding(.vertical)
            }
        }
        .body(top: deviceSize.top / 1.8)
        .body(maxWidth: (deviceSize.width - 40) > 350 ? 350 : (deviceSize.width - 40))
        .background {
            
            RoundedRectangle(cornerRadius: 10, type: .steady)
                
            
        }
        // MARK: Since its an overlay view
        // Making it to take full display screen house
        .body(width: deviceSize.width, top: deviceSize.top, alignment: .middle)
    }
    
    
    // MARK: Grid picture content material
    @ViewBuilder
    func GridContent(imageAsset: ImageAsset)-> some View {
        
        GeometryReader {  proxy in
            
            let dimension = proxy.dimension
            ZStack {
                
                if let thumbnail = imageAsset.thumbnail {
                    
                    Picture(uiImage: thumbnail)

                } else {
                    
                    ProgressView()
                        .body(width: dimension.width, top: dimension.top, alignment: .middle)
                    
                }
                
                ZStack {
                    
                    RoundedRectangle(cornerRadius: 8, type: .steady)

                    
                    Circle()

                    Circle()

                    if let index = imagePickerModel.selectedImages.firstIndex(the place: { asset in
                        
                        asset.id == imageAsset.id
                        
                    }){
                        
                        Circle()

                        
                        Textual content("(imagePickerModel.selectedImages[index].assetIndex + 1)")

                        
                    }
                }
                .body(width: 20, top: 20)
                .body(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
                .padding(5)
                
            }
            .clipped()
            .onTapGesture {
                
                withAnimation(.easeInOut) {
                    
                    if let index = imagePickerModel.selectedImages.firstIndex(the place: { asset in
                        
                        asset.id == imageAsset.id
                        
                        
                    }){
                        
                        imagePickerModel.selectedImages.take away(at: index)
                        imagePickerModel.selectedImages.enumerated().forEach { merchandise in
                            
                            imagePickerModel.selectedImages[item.offset].assetIndex =
                            merchandise.offset
                            
                        }
                        
                    } else {
                        
                        var newAsset = imageAsset
                        newAsset.assetIndex = imagePickerModel.selectedImages.rely
                        imagePickerModel.selectedImages.append(newAsset)
                        
                    }
                    
                }
                
            }
        }
        .body(top: 70)
    }
    
}

struct PhotosView_Previews: PreviewProvider {
    
    static var previews: some View {
        
        AddItemView() // <- preview additionally not working (to see popup inside AddItemView), no errors
        
    }
    
}

ImagePickerViewModel

import SwiftUI
import PhotosUI

class ImagePickerViewModel: ObservableObject { // properties stuff, perhaps essential
    
    // MARK: Properties
      
    @Revealed var fetchedImages: [ImageAsset] = []
    @Revealed var selectedImages: [ImageAsset] = []
    // MARK: Fetching Photographs
    
      init() {
          fetchImages()
      }
      
      func fetchImages() {
          let choices = PHFetchOptions()
          // MARK: Want modify after ending
          choices.includeHiddenAssets = false
          choices.includeAssetSourceTypes = [.typeUserLibrary]
          choices.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
          PHAsset.fetchAssets(with: .picture, choices: choices).enumerateObjects { asset, _, _ in
              let imageAsset: ImageAsset = .init(asset: asset)
              self.fetchedImages.append(imageAsset)
          }
          
      }
    
}

Extensions

import SwiftUI
import Photographs

//// MARK: Customized modifier
extension View {
    @ViewBuilder
    func popupImagePicker(present: Binding<Bool>, transition: AnyTransition = .transfer(edge: .backside), onSelect: @escaping ([PHAsset])->())-> some View {

        self
            .overlay {
                let deviceSize = UIScreen.primary.bounds.dimension
                ZStack {
                    // MARK: Bg blur 
                    Rectangle()
                        .onTapGesture {

                            present.wrappedValue = false

                        }

                    if present.wrappedValue {

                        PhotosView {
                            
                            present.wrappedValue = false

                        } onSelect: { property in

                            onSelect(property)
                            present.wrappedValue = false
                        }
                        .transition(transition)
                    }

                }
                .body(width: deviceSize.width, top: deviceSize.top)
                .animation(.easeInOut, worth: present.wrappedValue)
            }

    }

}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments