Hello,
I have collection view with context menu using contextMenuConfigurationForItemAt and I wanted to customize the preview, when user long presses and context menu is shown. Something maybe like in the Music app when you long press on an album it shows the album in bigger size...
I found some snippets online for highlightPreviewForItemAt and dismissalPreviewForItemAt but it just doesn't work. As soon as a implemented these delegate methods, nothing happens when I long press, not even the standard preview with context menu.
These two methods aren't being called at all. Do I need to do something else? Do I need the previewProvider when creating the context menu? It is my understanding that that is needed only when the item should also open further detail on tap - which is something I don't need and want.
Below is my relevant implementation:
private func shareMenuConfiguration(for itemAt: URL, indexPath: IndexPath) -> UIContextMenuConfiguration {
let share = UIAction(title: "Share".localized(), image: UIImage(systemName: "square.and.arrow.up")) { [unowned self] _ in
let shareVC = UIActivityViewController(activityItems: [itemAt], applicationActivities: nil)
if let cell = collectionView.cellForItem(at: indexPath) {
shareVC.popoverPresentationController?.sourceView = cell.contentView
shareVC.popoverPresentationController?.sourceRect = cell.contentView.bounds
}
self.present(shareVC, animated: true)
}
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
UIMenu(title: "", children: [share])
}
}
func collectionView(_ collectionView: UICollectionView, contextMenuConfiguration configuration: UIContextMenuConfiguration, highlightPreviewForItemAt indexPath: IndexPath) -> UITargetedPreview? {
guard let item = datasource.itemIdentifier(for: indexPath), let cell = collectionView.cellForItem(at: indexPath) as? GalleryImageCell else {
return nil
}
let parameters = UIPreviewParameters()
let visibleRect = cell.contentView.bounds.insetBy(dx: 1/3, dy: 1/3)
let visiblePath = UIBezierPath(roundedRect: visibleRect, cornerRadius: 4)
parameters.visiblePath = visiblePath
return UITargetedPreview(
view: cell.contentView,
parameters: parameters,
target: .init(container: collectionView, center: collectionView.convert(cell.contentView.center, from: cell.contentView))
)
}
func collectionView(_ collectionView: UICollectionView, contextMenuConfiguration configuration: UIContextMenuConfiguration, dismissalPreviewForItemAt indexPath: IndexPath) -> UITargetedPreview? {
guard let item = datasource.itemIdentifier(for: indexPath), let cell = collectionView.cellForItem(at: indexPath) as? GalleryImageCell else {
return nil
}
let parameters = UIPreviewParameters()
let visibleRect = cell.contentView.bounds.insetBy(dx: 1/3, dy: 1/3)
let visiblePath = UIBezierPath(roundedRect: visibleRect, cornerRadius: 4)
parameters.visiblePath = visiblePath
return UITargetedPreview(
view: cell.contentView,
parameters: parameters,
target: .init(container: collectionView, center: collectionView.convert(cell.contentView.center, from: cell.contentView))
)
}
Thanks!
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
After scanning the room I use the .export method passing a ModelProvider. Then I import the USDZ into a SCNView and continue processing the scene: I would like to apply a texture to the walls and floor, but I can't do it for the walls and floor because they don't contain the TextureCoordinates. Creating them from the USDZ file is not easy. I tried to combine the CapturedRoom data for the walls and floor only, adding the TextureCoordinates. I'm managing, but I'm struggling a lot. Isn't there an easier way to do it? Is there a ModelProvider planned for surfaces in the future? If so, where can I access the RoomPlan beta documentation?
Hello !
Since iOS/iPadOS 18 there is a new switch transition between tabs in UITabBarController where is a little zoom of the selected UIViewController.
At first, I thought that was a bug but I found the same animation on the Apple's apps (like music, shortcuts...)
On my app, this animation produce a little flash/blink white before zooming, it's not smooth like on Apple's apps.
I searched on documentation but I didn't found any topics about how to disable it or handled it better.
Is this possible to disabled it ?
We are experiencing difficulties with keyboard navigation focus within a view contained inside a UIPageViewController. The intended keyboard navigation sequence does not function as expected.
Expected Behavior:
Pressing the Tab key once should move the focus to the UIPageViewController, allowing the use of the Up and Down arrow keys to navigate between pages.
Pressing the Tab key a second time should shift the focus outside the UIPageViewController
Pressing the Tab key a third time should move the focus back to the UIPageViewController.
Actual Behavior:
The focus does not shift as described above.
Have sent a sample Xcode project to Apple demonstrating the issue (unfortunately it doesn't allow me to attach the zipped project here for some reason).
STEPS TO REPRODUCE
Set a breakpoint at viewDidAppear (line 44, MyViewController)
Run the app, wait until it stops, and run the command in the lldb debugger
Command:
po UIFocusDebugger.checkFocusability(for: pager.viewControllers!.first!.view.subviews.first!)
Output:
The following issues were found that would prevent this item from being focusable:
- ISSUE: One or more ancestors have issues that may be preventing this item from being focusable. Details:
<_UIQueuingScrollView: 0x104826a00>:
- ISSUE: This view returns YES from -canBecomeFocused, which will prevent its subviews from being focusable.
<_UIPageViewControllerContentView: 0x103d07be0>:
- ISSUE: This view returns YES from -canBecomeFocused, which will prevent its subviews from being focusable.
I'm working on an app that uses
UIPasteboard.general.string = "my text here"
to copy text to the user's pasteboared so that they can then paste from another device.
I'm doing this periodically based on conditions - so every 10-20 seconds, I have a new string to copy to the pasteboard. Consistently after 2 minutes, this stops working - the pasteboard on the local device updates, but my other devices don't receive the new pasteboard content. If I touch the screen of the device running my app to 'wake it up', it suddenly works again for another 2 minutes.
I've tried
UIApplication.shared.idleTimer = false
but it has had no effect. Is there a way to keep the universal pasteboard working without constant app interaction?
I have an iPad app using the new UITabBarController on iPadOS18, which is suffering from a new issue from the new layout. Within my tabs, I have a UISplitViewController, with a 2 column layout. If I load the app, it works ok, but if I put the app in the background, and then bring it to foreground, the navigation bar buttons and title just disappear from the splitView controller’s primary view controller.
Before going to background:
After coming back from background:
I also get the following layout issues posted in the debugger consoler:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600002106ee0 UILayoutGuide:0x600003b088c0'TitleView(layout=0x103d18d40)'.trailing <= UILayoutGuide:0x600003b08c40'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x600002137520 H:|-(590)-[UILayoutGuide:0x600003b00a80'TabBarGuide(0x103d18810)'](LTR) (active, names: '|':_UINavigationBarContentView:0x103d18810 )>",
"<NSLayoutConstraint:0x600002137610 UILayoutGuide:0x600003b00a80'TabBarGuide(0x103d18810)'.width == 0 (active)>",
"<NSLayoutConstraint:0x6000021414a0 UILayoutGuide:0x600003b088c0'TitleView(layout=0x103d18d40)'.trailing >= UILayoutGuide:0x600003b00a80'TabBarGuide(0x103d18810)'.trailing (active)>",
"<NSLayoutConstraint:0x600002148e10 'UIView-Encapsulated-Layout-Width' _UINavigationBarContentView:0x103d18810.width == 585 (active)>",
"<NSLayoutConstraint:0x600002107570 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600003b08c40'UIViewLayoutMarginsGuide']-(20)-|(LTR) (active, names: '|':_UINavigationBarContentView:0x103d18810 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002106ee0 UILayoutGuide:0x600003b088c0'TitleView(layout=0x103d18d40)'.trailing <= UILayoutGuide:0x600003b08c40'UIViewLayoutMarginsGuide'.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
I filed a bug report: FB14971801
Is there something I can do avoid this? It'll make my app pretty unusable if the bar button items just disappear every time the user puts the app in the background and then foregrounds the app.
Sample app
A collection view controller with list layout, 1 section and 1 row.
The cell's content view contains a text view.
class ViewController: UICollectionViewController {
var snapshot: NSDiffableDataSourceSnapshot<Section, String> {
var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
snapshot.appendSections([.main])
snapshot.appendItems(["one", "two"], toSection: .main)
return snapshot
}
var dataSource: UICollectionViewDiffableDataSource<Section, String>?
enum Section {
case main
}
init() {
super.init(collectionViewLayout: .init())
collectionView.collectionViewLayout = createLayout()
configureDataSource() // more likely and automatically avoid unpleasant animations on iOS 15 by configuring the data source in the init rather than in view did load
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
let textView = UITextView()
textView.font = .systemFont(ofSize: UIFont.labelFontSize)
cell.contentView.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textView.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 8),
textView.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: -8),
textView.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: cell.directionalLayoutMargins.leading),
textView.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: -cell.directionalLayoutMargins.trailing)
])
}
dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)
}
dataSource?.apply(self.snapshot, animatingDifferences: false)
}
func createLayout() -> UICollectionViewLayout {
return UICollectionViewCompositionalLayout { section, layoutEnvironment in
let config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
}
}
}
Question 1
Can anybody edit the provided sample code so that the text view's vertical indicator inset is not cut off at the top?
Question 2
It seems to me that Apple has successfully implemented text views inside table view cells: can anybody provide Apple documentation as per how to do so?
What I've tried and didn't work
textView.verticalScrollIndicatorInsets.top = 30 // does nothing
Adding the text view to a custom view and the view to the cell's content view
textView.contentInset = .zero
textView.scrollIndicatorInsets = .zero
textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 0
Centering the text view vertically and constraining its height to that of the content view with an 8 points constant to leave some padding
Constraining the top and bottom anchors of the text view to the cell's layout margins guide's top and bottom anchors
Constraint
I need the text view to have some padding from the top and bottom of the cell for aesthetic reasons.
I have a Catalyst app that plays audio via AVQueuePlayer, and I'd like to use the system play/pause key (F8 on my MacBook Pro keyboard) to play and pause it. It doesn't seem to work automatically, and if I hook up a UIKeyCommand using UIKeyInputF8, it works with Fn-F8, not F8 on its own.
It does seem to work in Overcast's Mac app, but I think that's an iPad app for Mac, not Catalyst, so it's probably going through whatever system pathway that the Lock Screen controls would be using on iOS.
How do I make this work on Catalyst?
Under iPadOS 18, I would like the main content to remain the same size regardless of whether the tab bar is hidden or visible.
Is there an easy way to do this?
In our app, we noticed that edit menus (i.e. when long pressing in a text field) have weird spacing inside each element. Which, as a result, causes the entire menu content to be truncated.
To be honest, I have no idea how this is being customized (to my understanding it shouldn't be?), but this is a relatively old and large app so something weird could possibly do it. I basically came here for guidance to see if anyone has thoughts on WHAT could possibly cause this customization / padding / resizing of each item, so I can fix it back to the system behavior.
Our app:
System:
Thanks for your help :)
Shai
Having below issues with Navigation bar in UISplitViewController Primary View Controller,
Navigation title is not showing with new Elevated Tab bar.
Navigation right bar button is not showing.
Navigation bar height issue with Primary and Secondary View
Working fine in iPad OS 17.
SplitViewController preferred display mode is
preferredDisplayMode = UISplitViewController.DisplayMode.oneBesideSecondary
Tested with Xcode 16.1 Beta and Xcode 16.0 Beta 6
iPad OS 18.1
iPadOS 17.5
I found two tab bar issues:
How do you programmatically hide/show the tab bar for iPadOS and Catalyst apps under macOS Sequoia? Also, is there a way to prevent the user from doing this via the menu?
Programmatically changing the current tab view correctly changes the tab view but not the tab item highlighted in the tab bar in:
Mac Catalyst apps under Sequoia
iPad apps under Sequoia
tvOS 18 apps
Is there a workaround I can use until this bug is fixed?
Problem
When I reconfigure a collection view snapshot and apply it to my complex production collection view with list layout, the UI updates slowly, unless I don't animate the differences, even though I'm only reconfiguring the specific item identifiers of the cells that should be updated.
I thought that maybe I could speed up the animations of the UI updates by applying the snapshot to a specific section (dataSource?.apply(sectionSnapshot, to: .main)) instead of to the whole collection view (dataSource?.apply(wholeSnapshot)).
The problem is that I can't reconfigure the item identifiers of a single section snapshot to then apply the updated snapshot.
Question
Given the following sample app, can anybody edit reconfigureMainSection() so that, when invoked, the .main section cell registrations are called, consequently invoking print("Reconfiguring")?
Sample app
This collection view with list layout and diffable data source has 1 section and 2 rows.
You can tap the right bar button item to call reconfigureMainSection().
class ViewController: UICollectionViewController {
var snapshot: NSDiffableDataSourceSnapshot<Section, String> {
var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
snapshot.appendSections([.main])
snapshot.appendItems(["one", "two"], toSection: .main)
return snapshot
}
var dataSource: UICollectionViewDiffableDataSource<Section, String>?
enum Section {
case main
}
init() {
super.init(collectionViewLayout: .init())
collectionView.collectionViewLayout = createLayout()
configureDataSource()
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = .init(
title: "Reconfigure",
style: .plain,
target: self,
action: #selector(reconfigureMainSection)
)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
print("Reconfiguring")
}
dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)
}
dataSource?.apply(self.snapshot, animatingDifferences: false)
}
func createLayout() -> UICollectionViewLayout {
return UICollectionViewCompositionalLayout { section, layoutEnvironment in
let config = UICollectionLayoutListConfiguration(appearance: .plain)
return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
}
}
@objc func reconfigureMainSection() {
var sectionSnapshot = NSDiffableDataSourceSectionSnapshot<String>()
sectionSnapshot.append(snapshot.itemIdentifiers(inSection: .main))
// reconfigure the section snapshot
dataSource?.apply(sectionSnapshot, to: .main)
}
}
Environment
MacBook Air M1 8GB
macOS Sonoma 14.5
Xcode 15.4
iPhone 15 Pro simulator on iOS 17.5
In iOS 18, the tab bar has been moved to the top on iPad. How can I hide this tab bar? Using TabBarController.tabBar.isHidden = true isn't working.
Xcode version: Xcode16 beta6
iOS version:iOS18 beta7
The openURL method call to UIApplication is invalid
Moreover, the project has a lot of logic dependent on the return value of this method, which is very troublesome to modify
Look at the Apple documentation, and say that the problem is fixed, how should I deal with this situation
It's working well on iOS 17 simulator and device. but crashes on iOS 18 beta. It looks like it crashes on a UIviewcontroller page with a UIcollectionView.
I have a UIViewController that presents a UIPrintInteractionController when a user selects the print button on the UI. The problem is starting in iOS 18 (currently using beta 7) when the print controller is presented the UIViewController's viewWillAppear() is being called. This did not happen in earlier iOS releases and is causing unwanted behavior in the app. Is this a bug or will this be the behavior going forward?
Hello. I'm encountering a strange behavior in iOS 18 and wanted to ask about it.
When I run the following code on iOS 18, quotation marks appear in the navigation title.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = " "
self.view.backgroundColor = .systemBlue
}
}
In versions prior to iOS 18, the title is displayed as intended, with nothing showing up. Could this be an intentional change in iOS 18, or is it a bug?
For a few reasons, we as a team decided to transition away from the SwiftUI.App launch cycle. We need more control and customisation, and managing the scenes directly ourselves was the best way forward.
We're now trying to run the app entirely from our own App and Scene delegates, however we've run into a problem: When we update the app on a device from a version that uses SwiftUI.App to a version that uses App and Scene delegates, the first initial launch fails with a black screen.
The reason for this is that FrontBoardServices attempts to use the existing UISceneSession after the update, with the SwiftUI.AppSceneDelegate class, instead of calling application(configurationForConnecting:options:). Since SwiftUI.AppSceneDelegate still exists in the scope, the internal property _configurationNeedsReevaluation on UISceneSession returns false and the app attempts to launch from SwiftUI.AppSceneDelegate.
As far as I can tell, there doesn't seem to be a way to fix this that doesn't involve invoking the private method -[UISceneSession _updateConfiguration:] to force the configuration to use the correct Scene delegate.
if let sceneSession = application.openSessions.first(
where: { $0.configuration.delegateClass.map(NSStringFromClass) == "SwiftUI.AppSceneDelegate" }
) {
let newConfig = UISceneConfiguration(name: nil, sessionRole: .windowApplication)
newConfig.delegateClass = SceneDelegate.self
sceneSession.perform(Selector(("_updateConfiguration:")), with: newConfig)
}
Could you maybe advise on a way forwards?
when I push a UIViewController, the bottom view controller was pushed out of navigationController.