Doesn't work in WatchOS either, tried everything I can think of. Plain project with nothing but a TextField and an .onAppear{} modifier with a .main.asyncAfter{} with 1 second delay changing the focus state does not do anything. Focus always prints nil/false... how does this even slip by QA, idk.
Post
Replies
Boosts
Views
Activity
@Kirill-Avdeenko I posted below how I do this.
As per request of commenter's of this post, this is how I set up the container view which holds the reactionView for the cell:
func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
guard
let indexPath = configuration.identifier as? IndexPath,
let cell = tableView.cellForRow(at: indexPath) as? MessageTableViewCell
else {
return nil
}
ctxMenuReactionsView = ReactionsView.setup()
ctxMenuReactionsView?.isHidden = true /* must set isHidden = false in the delegate method I mentioned in checkmark'd answer */
if let snapshot = cell.snapshotView(afterScreenUpdates: false) { /* snapshot the view of the cell for displaying in container */
snapshot.isHidden = false
snapshot.layer.cornerRadius = 10
snapshot.layer.masksToBounds = true
snapshot.translatesAutoresizingMaskIntoConstraints = false
/* create the container that the snapshot and reactionView will be in */
let container = UIView(frame: CGRect(
origin: .zero,
size: CGSize(
width: cell.bounds.width,
height: cell.bounds.height + ctxMenuReactionsView!.bounds.height + 5
)
))
container.backgroundColor = .clear
container.addSubview(ctxMenuReactionsView!)
container.addSubview(snapshot)
/* set up constraints for snapshot and ReactionsView */
ctxMenuReactionsView?.leftAnchor.constraint(equalTo: container.leftAnchor).isActive = true
ctxMenuReactionsView?.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
ctxMenuReactionsView?.widthAnchor.constraint(...)
container.addConstraints([
...
])
var centerPoint = CGPoint(x: cell.center.x, y: cell.center.y - ctxMenuReactionsView!.bounds.height)
let windowHeight = self.view.window?.size.height ?? 0
if snapshot.bounds.height > (windowHeight * 0.9) { /* if the snapshot of cell if too tall, we use this center point to make it fit */
centerPoint = CGPoint(x: cell.center.x, y: tableView.center.y)
}
let previewTarget = UIPreviewTarget(container: tableView, center: centerPoint)
/* makes sure background of the container is clear */
let parameters = UIPreviewParameters()
parameters.backgroundColor = .clear
if #available(iOS 14.0, *) { /* this removes the shadow from the container */
parameters.shadowPath = UIBezierPath()
}
return UITargetedPreview(view: container, parameters: parameters, target: previewTarget)
}
Be sure to pass in the indexPath of the cell in the func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) - UIContextMenuConfiguration? function in the identifier paramater like so:
return UIContextMenuConfiguration(identifier: indexPath as NSCopying,
previewProvider: nil,
actionProvider:
{
... set up menu items code
}
I was able to solve the second problem listed (#2.) by used the UITableViewDelegate method func tableView(_ tableView: UITableView, willDisplayContextMenu configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?). I did this by setting the reaction's view isHidden property to true during setup and then subsequently adding an animation to the animator of the delegate function willDisplayContextMenuto set isHidden back to false. This makes it so the reaction view appears at the same time as the ContextMenu!
As for the duration of the long press, I have decided that was ancillary and of low priority which. with this above solution, is not as much of importance.
Hope this helps some devs out there.
Addendum: How would I accomplish what I described above?
This is still an issue. Tested it myself today. Bold + Italic and headers were not working.