Posts

Post marked as solved
7 Replies
First and foremost, thank you very much for taking the time and effort to answer my questions. This is my first project and some things are hard to find an answer for. It now works beautifully, here is the working code for those who might experience the same problems. in my ViewController    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {     //Expandable cell     guard let cell = tableView.cellForRow(at: indexPath) as? AnnotationCell else { return }     cell.toggleFullView()     tableView.beginUpdates()     tableView.endUpdates()   } and the reworked toggleMethod:    ///Expand and collapse the cell   func toggleFullView() {     //Show the full contents     print("ShowFullDetails = \(showFullDetails.description.uppercased())")     if showFullDetails {       print("Show full contents")       if contentView.subviews.contains(previewDetailsView) {         previewDetailsView.removeFromSuperview()       }       if !contentView.subviews.contains(fullDetailsView) {         contentView.addSubview(fullDetailsView)       }       NSLayoutConstraint.activate([         fullDetailsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding),         fullDetailsView.leadingAnchor.constraint(equalTo: checkmarkView.trailingAnchor, constant: padding),         fullDetailsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -2 * padding),         fullDetailsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -padding)       ])     //Show preview contents     } else {       print("Show preview contents")       if contentView.subviews.contains(fullDetailsView) {         fullDetailsView.removeFromSuperview()       }       if !contentView.subviews.contains(previewDetailsView) {         contentView.addSubview(previewDetailsView)       }       NSLayoutConstraint.activate([         previewDetailsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding),         previewDetailsView.leadingAnchor.constraint(equalTo: checkmarkView.trailingAnchor, constant: padding),         previewDetailsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -2 * padding),         previewDetailsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)       ])     }           showFullDetails.toggle()     //Invalidate current layout &     self.setNeedsLayout()   } Now only a reusable cell issue remains, but i'll make a new topic about that! Thanks again!
Post marked as solved
7 Replies
Ok, now I got some action with .SetNeedslayout() It animates and changes back and forth with one click, BUT ... The cell does not adjust its size to the content and stays the size of the first view (previewDetailsView). How could I make it so it sizes to fit the content ? (which it does with the reloadData way)    ///Expand and collapse the cell    func toggleFullView() {      showFullDetails.toggle()            if showFullDetails {        //show the full version        if contentView.subviews.contains(previewDetailsView) {          previewDetailsView.removeFromSuperview()        }        if !contentView.subviews.contains(fullDetailsView) {          contentView.addSubview(fullDetailsView)        }      } else {        //show the preview version        if contentView.subviews.contains(fullDetailsView) {          fullDetailsView.removeFromSuperview()        }        if !contentView.subviews.contains(previewDetailsView) {          contentView.addSubview(previewDetailsView)        }      }     //Invalidate the layout     contentView.setNeedsLayout()            UIView.animate(withDuration: 1.2) {       self.layoutIfNeeded()      }    }
Post marked as solved
7 Replies
Thank you for your reply There's indeed a gesturerecognizer attached to the cell/tableview. How would that interfere?    private func configureTableView() {     tableView = UITableView(frame: view.bounds, style: .grouped)     tableView.delegate = self     tableView.dataSource = self     tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]     tableView.backgroundColor = .clear     view.addSubview(tableView)           tableView.register(AnnotationCell.self, forCellReuseIdentifier: AnnotationCell.reuseIdentifier)     tableView.register(AnnotationHeaderCell.self, forHeaderFooterViewReuseIdentifier: AnnotationHeaderCell.reuseIdentifier)           //Dynamic sizing cells     tableView.sectionHeaderHeight = 40     tableView.rowHeight = UITableView.automaticDimension     tableView.estimatedRowHeight = 70           //Tap and hold to edit annotation     let tapAndHold = UILongPressGestureRecognizer(target: self, action: #selector(tapAndHoldCell))     tapAndHold.minimumPressDuration = 0.3     tableView.addGestureRecognizer(tapAndHold)   }    @objc private func tapAndHoldCell(recognizer: UILongPressGestureRecognizer) {     if recognizer.state == .ended {       guard let indexPath = tableView.indexPathForRow(at: recognizer.location(in: self.tableView)) else { return }       let annotation = annotationsController.getAnnotationFor(indexPath)               let viewController = AnnotationDetailsViewController(withAnnotation: annotation)       viewController.delegate = self       navigationController?.pushViewController(viewController, animated: true)     }   }
Post not yet marked as solved
3 Replies
Thank you! I'll try reloadItemsWithIdentifier The warning you are seeing about "UITableView was told to layout its visible cells and other contents without being in the view hierarchy" probably means you are calling apply before UITableView is in a window. The most common case where this happens is if you call apply from inside a view controllers viewDidLoad, where the view was loaded but is not yet in the view hierarchy. About the tableView issue. On first load I do call apply from viewDidLoad and got away with the warning by forcing it on the main queue:     DispatchQueue.main.async {       self.dataSource.apply(snapshot, animatingDifferences: true)     } Where would be more appropriate to call apply() ? However, when saving or updating an annotation the. situation is different. The ViewController is already loaded and pushes another ViewController on top to add or edit and existing annotation. When the user taps save, a delegate method is called on the original ViewController (the save method in my post). That's when I get the warning. How do I prevent that warning in this case ? To summarize: AnnotationsViewController > AnnotationDetailsViewController > Calls save() on AnnotationsViewController (delegate method) Also, I don't use storyboards, all programmatic UI