Posts

Post not yet marked as solved
0 Replies
376 Views
I have a collectionview with a custom flowlayout and a custom collectionview cell (no storyboards). The custom cell has a CAGradientLayer on a background view. When coming back from suspended state this layer is rendered incorrectly (see image: http://www. gakkie.nl/images/gradientlayerrendering.png *remove the space*). It should be the full width of the cell. I'm not sure if this is solvable in the custom cell class or in the collectionview viewcontroller. Both as text included. Collectionview custom cell class - https://developer.apple.com/forums/content/attachment/2aa8b883-cdd2-4b22-af38-dd1e006b5192 CollectionView viewcontroller - https://developer.apple.com/forums/content/attachment/0b6757c2-f9e9-476c-b6d2-1a90c1d0ba27 Any help greatly appreciated!
Posted
by gakkie.
Last updated
.
Post marked as solved
7 Replies
3.4k Views
In my project (UIKit, programmatic UI) I have a UITableView with sections. The cells use a custom class. On load all cells just show 3 lines of info (2 labels). On tap, all contents will be displayed. Therefor I've setup my custom cell class to have two containers, one for the 3 line preview and one for the full contents. These containers are added/removed from the cell's content view when needed when the user taps the cell by calling a method (toggleFullView) on the custom cell class. This method is called from the view controller in didSelectRowAt: 		func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 				let annotation = annotationsController.getAnnotationFor(indexPath) 				//Expandable cell 				guard let cell = tableView.cellForRow(at: indexPath) as? AnnotationCell else { return } 				cell.toggleFullView() 				tableView.reloadRows(at: [indexPath], with: .none) //				tableView.reloadData() 		} Basically it works, but there are some issues: I have to double tap the cell for it to expand and again to make it collapse again. The first tap will perform the row animation of tableView.reloadRows(at: [indexPath], with: .none) and the second tap will perform the expanding. If I substitute reloadRows with tableView.reloadData() the expanding and collapsing will happen after a single tap! But that is disabling any animations obviously, it just snaps into place. How Do I get it to work with one tap? When the cell expands, some other random cells are also expanded. I guess this has something to do with reusable cells, but I have not been able to remedy this. I want to be the expanded cell to collapse once I tap another cell to expand, how do I perceive that? My custom cell class (partly): [AnnotationCell full cell class](https://developer.apple.com/forums/content/attachment/caacbef0-2e20-4528-b86a-859d1ceb460f){: .log-attachment} import UIKit class AnnotationCell: UITableViewCell, SelfConfiguringAnnotationCell { 		//MARK: - Actions 		///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) 						} 				} 				UIView.animate(withDuration: 1.2) { 						self.layoutIfNeeded() 				} 		} Would be great to at least no longer have multiple random cells expand on tap
Posted
by gakkie.
Last updated
.
Post not yet marked as solved
3 Replies
4.2k Views
I have a UITableVIew with a UITableViewDiffableDataSource. The tableView also uses and custom Cell Class. Adding Items essentially works. By tapping and holding a cell I go to a viewController where I can update/change several fields of my item. Here's the method used :    func save(_ annotation: Annotation, withMapImage mapImage: AnnotationsController.MapImage?) {     //Save the project to update Last Edited     projectsController.save(annotationsController.project, withImage: nil)     //Get current snapshot     var snapshot = dataSource.snapshot()           //Replace updated annotation by deleting old version from snapshot first     if snapshot.itemIdentifiers.contains(annotation) {       snapshot.deleteItems([annotation])     }           snapshot.appendItems([annotation], toSection: annotation.type)           //Apply the snapshot on the main thread     DispatchQueue.main.async {       self.dataSource.apply(snapshot, animatingDifferences: true)       self.tableView.reloadData()     }           //Save to storage     annotationsController.save(annotation, withMapImage: nil)   } Two options: 1) With all of the above code in place, the changes are reflected in the tableView, but ONLY when the self.tableView.reloadData() is there! But this shouldn't be necessary with a diffable dataSource? 2) if I omit the if snapshot.itemIdentifiers.contains(annotation) { ... the changes are also reflected immediately, but the console throws a warning: [UIDiffableDataSource] Warning: 1 inserted identifier(s) already present; existing items will be moved into place for this current insertion. Please note this will impact performance if items are not unique when inserted. TL;DR What's the correct way of updating an existing item when using a UITableViewDiffableDataSource? ALSO, on a side note: when I insert the very first item into the DataSource/Snapshot I get a warning also TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: &lt;UITableView: 0x7f9213826200; frame = (0 0; 414 896); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6000035ff780&gt;;  I thought that forcing the .apply() on the main thread should prevent that? Programmatic UI, no storyboards, I do add tableView as subview to the view!
Posted
by gakkie.
Last updated
.
Post not yet marked as solved
2 Replies
1.1k Views
I have an app with a programmatic UI (No storyboards). I add a context menu to a button of my viewcontroller. On opening this menu (tap and hold on the button) I get a LayoutConstraints warning/error in the console (menu works fine otherwise): ( &#9;&#9;"&lt;NSAutoresizingMaskLayoutConstraint:0x600001c9ed50 h=--&amp; v=--&amp; UIInterfaceActionGroupView:0x7f9d4478ceb0.height == 0&#9; (active)&gt;", &#9;&#9;"&lt;NSLayoutConstraint:0x600001cd7c50 groupView.actionsSequence....height &gt;= 66&#9; (active, names: groupView.actionsSequence...:0x7f9d4610ee00 )>", &#9;&#9;"&lt;NSLayoutConstraint:0x600001cb3de0 UIInterfaceActionGroupView:0x7f9d4478ceb0.top == _UIContentConstraintsLayoutGuide:0x7f9d4478bba0''.top&#9; (active)&gt;", &#9;&#9;"&lt;NSLayoutConstraint:0x600001cb3e80 V:[_UIContentConstraintsLayoutGuide:0x7f9d4478bba0'']-(0)-|&#9; (active, names: '|':UIInterfaceActionGroupView:0x7f9d4478ceb0 )&gt;", &#9;&#9;"&lt;NSLayoutConstraint:0x600001cad090 groupView.actionsSequence....top == _UIContentConstraintsLayoutGuide:0x7f9d4478bba0''.top&#9; (active, names: groupView.actionsSequence...:0x7f9d4610ee00 )&gt;", &#9;&#9;"&lt;NSLayoutConstraint:0x600001cad130 groupView.actionsSequence....bottom == _UIContentConstraintsLayoutGuide:0x7f9d4478bba0''.bottom&#9; (active, names: groupView.actionsSequence...:0x7f9d4610ee00 )&gt;" ) Will attempt to recover by breaking constraint &lt;NSLayoutConstraint:0x600001cd7c50 groupView.actionsSequence....height &gt;= 66&#9; (active, names: groupView.actionsSequence...:0x7f9d4610ee00 )> this groupView is not a view of mine! I have set translatesAutoresizingMaskIntoConstraints = false on all my custom controls (labels, fields, etc). I presume I need to set that to for the context menu somewhere, but I don't know how or where. Relevant code: In my viewcontroller: &#9;&#9;&#9;&#9;let interaction = UIContextMenuInteraction(delegate: self) &#9;&#9;&#9;&#9;annotationTypeButton.addInteraction(interaction) Delegate extension: //MARK: - UIContextMenuInteractionDelegate extension AnnotationDetailsViewController: UIContextMenuInteractionDelegate { &#9;&#9;func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { &#9;&#9;&#9;&#9;return UIContextMenuConfiguration(identifier: "annotationTypeMenu" as NSCopying, previewProvider: nil) { _ in &#9;&#9;&#9;&#9;&#9;&#9;let children: [UIMenuElement] = self.makeAnnotationTypeActions() &#9;&#9;&#9;&#9;&#9;&#9;return UIMenu(title: "", children: children) &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9; &#9;&#9;func makeAnnotationTypeActions() -> [UIAction] { &#9;&#9;&#9;&#9;var actions = [UIAction]() &#9;&#9;&#9;&#9;for type in AnnotationType.allCases { &#9;&#9;&#9;&#9;&#9;&#9;actions.append( UIAction(title: type.rawValue, image: type.image, identifier: nil, attributes: []) { _ in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;let annotationType = AnnotationType(rawValue: type.rawValue) ?? AnnotationType.tips &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.annotation.type = annotationType &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.configureAnnotationTypeButton(with: annotationType) &#9;&#9;&#9;&#9;&#9;&#9;}) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;return actions &#9;&#9;} } Any help appreciated! On a side note. If I leave a warning like this in, will my app pass and get into the app store?
Posted
by gakkie.
Last updated
.