Tuesday, June 25, 2024
HomeiOS Developmentios - SwiftUI ScrollView not scrolling to textual content area when a...

ios – SwiftUI ScrollView not scrolling to textual content area when a UIViewRepresentable is rendered


I am at present creating some replace in our views and we have now a view which is completely made in SwiftUI. This view has ScrollView, which earlier than we nested a UIViewRepresentable, it used to scroll to the TextField, when this area was centered.

struct PinDetailViewSwiftUI {

    var physique: some View {

            ScrollView {
                VStack(spacing: 0) {
                    GeometryReader { proxy in
                        let offset = proxy.body(in: .named("scroll")).minY
                        Shade(GrayColors.gray10.getColor()).desire(key: ViewOffsetKey.self, worth: offset)
                    }
                    
                    if pinViewModel.isLoadingData {
                        PinDetailLoadingViewSwiftUI()
                    } else {
                        PinSectionHeaderView(title: DTTaskListTranslate.splitViewTasks.translation)
                        if !pinViewModel.duties.isEmpty || pinViewModel.tasksHasChanged {
                            
                            NavigationLink(vacation spot: PinTaskDetailSwiftUI(duties: .fixed(pinViewModel.duties), selectedTask: pinViewModel.preSelectedTask, pin: pinViewModel.pinModel, userRole: challenge.roleType ?? .SubContractor, viewMode: .view, reassign: false), isActive: $pinViewModel.openPreSelectedTask) {
                                EmptyView()
                            }.buttonStyle(PlainButtonStyle())
                            
                            SwiftUI.Group {
                                TaskPreviewRepresentable(process: pinViewModel.duties[0], userImage: .fixed(nil), userRole: challenge.roleType ?? .SubContractor, viewModel: viewModel)
                                    .body(peak: viewModel.getHeightOfTaskPreview(process: process, userRole: challenge.roleType ?? .SubContractor), alignment: .middle)
                            }
                            .animation(.easeInOut)
                        }
                        
                        if pinViewModel.pinModel != nil  && pinViewModel.userCanCreateTasks() {
                            NavigationLink(isActive: $pinViewModel.showTaskCreationView) {
                                PinTaskDetailSwiftUI(duties: $pinViewModel.duties, selectedTask: DTMediaPost.getDefaultTask(pin: pinViewModel.pinModel), pin: pinViewModel.pinModel, userRole: challenge.roleType ?? .SubContractor, viewMode: .create, reassign: false)
                            } label: {
                                Button(motion: {
                                    if !pin.isPinClosedOrInactive {
                                        pinViewModel.showTaskCreationView.toggle()
                                    } else {
                                        pinViewModel.showPinClosedAlert.toggle()
                                    }
                                }, label: {
                                    PinCreateNewTask()
                                })
                            }
                            .body(peak: 50)
                        }
                        
                        PinSectionHeaderView(title: DTPinTranslate.pinFieldsHeader.translation)
                        
                        if !pinViewModel.datasets.isEmpty {
                            PinDatasetView(linkedDatasets: $pinViewModel.linkedRecords, information: $pinViewModel.datasets, datasetChanged: $pinViewModel.datasetChanged, showPinClosedAlert: $pinViewModel.showPinClosedAlert, pin: pinViewModel.pinModel)
                            
                            Rectangle()
                                .body(maxWidth: .infinity)
                                .body(peak: 1)
                                .foregroundColor(.grey.opacity(0.2))
                                .padding([.bottom, .top], 8)
                        }
                        
                        if !pinViewModel.pinFields.isEmpty {
                            
                            SwiftUI.Group {
                                ForEach(pinViewModel.pinFields, id: .id!) { worth in
                                    swap worth.sort! {
                                    case .quantity:
                                        PinTextFieldView(pinModel: $pinViewModel.pinModel, numberPinField: worth as! DTNumberPinField, canEdit: pinViewModel.pinModel.canPinBeChanged)
                                    case .date:
                                        PinDateView(pin: $pinViewModel.pinModel, dtPinDateField: worth as! DTPinDateField, canEdit: pinViewModel.pinModel.canPinBeChanged)
                                    case .slider:
                                        PinSliderView(pinSliderScale: worth as! DTPinSliderField, pinModel: $pinViewModel.pinModel, categoryColor: $pinViewModel.pinCategoryColor, canEdit: pinViewModel.pinModel.canPinBeChanged)
                                    case .textual content:
                                        PinTextAreaView(textPinField: worth as! DTTextPinField, canEdit: pinViewModel.pinModel.canPinBeChanged, pinModel: $pinViewModel.pinModel)
                                    case .tags:
                                        VStack {
                                            if showTagSuggestions {
                                                PinTagSuggestionView(suggestedTags: $pinViewModel.suggestedTags, recentTags: $pinViewModel.filteredRecentTags, searchedTag: $pinViewModel.currentTagBeingAdded)
                                                    .body(peak: pinViewModel.getRecentTagsHeight())
                                            }
                                            PinTagsView(showTagSuggestions: $showTagSuggestions, currentTagBeingAdded: $pinViewModel.currentTagBeingAdded, canBeEdited: pinViewModel.pinModel.canPinBeChanged, tagField: worth, pin: $pinViewModel.pinModel)
                                        }
                                        
                                    case .time:
                                        PinTimeFieldView(pinModel: $pinViewModel.pinModel, timePinField: worth as! DTPinTimeField)
                                    }
                                    
                                    Rectangle()
                                        .body(maxWidth: .infinity)
                                        .body(peak: 1)
                                        .foregroundColor(.grey.opacity(0.2))
                                        .padding([.bottom, .top], 8)
                                }
                            }
                        }
                        
                        if !pinViewModel.visualMediaPosts.isEmpty, !isCameraOpened {
                            PinMediaView(medias: $pinViewModel.visualMediaPosts, pin: pinViewModel.pinModel, numberOfMedias: pinViewModel.numberOfElementsInPin())
                                .body(peak: pinViewModel.getTotalHeightForMediaSection())
                        }
                        
                        if !pinViewModel.mediaPosts.isEmpty,
                            !isCameraOpened {
                            PinSectionHeaderView(title: DTSharedTranslate.exercise.translation)
                            
                            if #obtainable(iOS 16.0, *) {
                                PinActivityViewList(mediaPosts: pinViewModel.mediaPosts, pin: pinViewModel.pinModel, isLastPage: pinViewModel.isLastPage, pinDetailViewModel: .fixed(pinViewModel), isLoading: pinViewModel.isLoadingMedia, loadNextPage: $pinViewModel.loadNextPage)
                                    .body(peak: pinViewModel.getTotalHeightForActivitySection())
                                    .animation(.easeInOut)
                                    .scrollContentBackground(.hidden)
                            } else {
                                PinActivityViewList(mediaPosts: pinViewModel.mediaPosts, pin: pinViewModel.pinModel, isLastPage: pinViewModel.isLastPage, pinDetailViewModel: .fixed(pinViewModel), isLoading: pinViewModel.isLoadingMedia, loadNextPage: $pinViewModel.loadNextPage)
                                    .body(peak: pinViewModel.getTotalHeightForActivitySection())
                                    .animation(.easeInOut)
                                
                            }
                        }
                    }
                }
                .background(Shade.white)
                .navigationBarHidden(true)
            }
            .background(Shade(GrayColors.gray10.getColor()))
            .coordinateSpace(identify: "scroll")
            .onPreferenceChange(ViewOffsetKey.self) { worth in
                if pinViewModel.galleryViewHeight >= 0.0 && pinViewModel.galleryViewHeight <= pinViewModel.kGalleryHeightConst {
                    let previousValue = pinViewModel.galleryViewHeight + worth
                    if previousValue <= 0.0 {
                        pinViewModel.galleryViewHeight = 0
                    } else if previousValue >= pinViewModel.kGalleryHeightConst {
                        pinViewModel.galleryViewHeight = pinViewModel.kGalleryHeightConst
                    } else {
                        pinViewModel.galleryViewHeight = previousValue
                    }
                }
            }
     }
}

As you’ll be able to see within the code above, the: PinTextFieldView, PinDateView, PinTextAreaView are all textual content fields, which once we faucet on it, strikes the scroll view and focus them.

This behaviour used to work tremendous, till the second we added a brand new class: TaskPreviewRepresentable, which is only a XIB executed in UIKit, which renders one other object that we fetch from the backend.

On this view we have now only some buttons and labels, all of the constraints are arrange accurately, however for some purpose, I nonetheless cannot get the ScrollView, to scroll to the sphere when it is centered.

Has anybody ever confronted this subject, which the ScrollView stops to give attention to a textual content area, solely since you added a UIViewRepresentable to it?

That is the code for the TaskPreviewRepresentable

struct TaskPreviewRepresentable: View, UIViewRepresentable {

    @Binding var process: DTMediaPost
    @Binding var userImage: UIImage?
    var userRole: RoleType
    @SwiftUI.State var viewModel: CardTaskViewModel
    
    func makeUIView(context: Context) -> DTTaskPreview {

        let taskPreview = DTTaskPreview(body: .init(x: 0, y: 0, width: UIDevice.isiPad ? viewModel.pinDetailiPadWidth - 32 : UIScreen.foremost.bounds.width - 32, peak: self.viewModel.getHeightOfTaskPreview(process: process, userRole: userRole)))
        
        taskPreview.setupTaskStatus(taskStatus: NewTaskStatus(dtMediaPost: process))
        taskPreview.setTaskStatusLabel(worth: NewTaskStatus(dtMediaPost: process).getName().lowercased())
        taskPreview.setTaskNumber(worth: DTTaskListTranslate.taskListNumber.translation+" "+(process.quantity.unwrapped == 0 ? "-" : String(process.quantity.unwrapped)))
        taskPreview.setTaskDescription(worth: process.title.unwrapped)
        taskPreview.setTaskCreatedOrLastModified(worth: viewModel.getLastModifiedString(process: process))
        taskPreview.setAssigneeImage(picture: viewModel.userImage, placeholder: process.getAssigneePlaceholder)
        
        var mainAction: TaskQuickAction?
        var secondaryAction: TaskQuickAction?
        (secondaryAction, mainAction) = viewModel.getMainAndSecondaryAction(userRole: userRole, process: process)

        if let leftAction = secondaryAction {
            taskPreview.setLeftButton(buttonSize: .medium, buttonStyle: .tertiary)
            taskPreview.setActionForLeftButton(actionName: leftAction.getOptionTranslation(), quickAction: leftAction)
        } else {
            taskPreview.hideLeftButton(hidden: true)
        }
        
        if let mainAction = mainAction {
            taskPreview.setRightButton(buttonSize: .medium, buttonStyle: .callToAction)
            taskPreview.setActionForRightButton(actionName: mainAction.getOptionTranslation(), quickAction: mainAction)
        } else {
            taskPreview.hideRightButton(hidden: true)
        }
        taskPreview.hideButtonView(hidden: (mainAction == nil && secondaryAction == nil))
        
        taskPreview.setAssigneeName(worth: process.task?.identify ?? "")
        taskPreview.setAssigneeSecondLine(worth: viewModel.getAssigneeSecondLineString(process: process))
        taskPreview.setDueDateLabel(worth: process.due)
        taskPreview.delegate = viewModel
        
        return taskPreview
    }

    func updateUIView(_ uiView: DTTaskPreview, context: Context) {
        uiView.setAssigneeImage(picture: viewModel.userImage, placeholder: process.getAssigneePlaceholder)
    }
    
}



Supply hyperlink

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments