Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Posts under UIKit tag

723 Posts
Sort by:
Post not yet marked as solved
1 Replies
51 Views
The following is a UIKit app that uses a collection view with list layout and a diffable data source. It displays one section that has 10 empty cells and then final cell whose content view contains a text view, that is pinned to the content view's layout margins guide. The text view's scrolling is set to false, so that the line collectionView.selfSizingInvalidation = .enabledIncludingConstraints will succeed at making the text view's cell resize automatically and animatedly as the text changes. import UIKit class ViewController: UIViewController { var collectionView: UICollectionView! var dataSource: UICollectionViewDiffableDataSource<String, Int>! let textView: UITextView = { let tv = UITextView() tv.text = "Text" tv.isScrollEnabled = false return tv }() override func viewDidLoad() { super.viewDidLoad() configureHierarchy() configureDataSource() if #available(iOS 16.0, *) { collectionView.selfSizingInvalidation = .enabledIncludingConstraints } } func configureHierarchy() { collectionView = .init(frame: .zero, collectionViewLayout: createLayout()) view.addSubview(collectionView) collectionView.frame = view.bounds collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] } func createLayout() -> UICollectionViewLayout { let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped) return UICollectionViewCompositionalLayout.list(using: configuration) } func configureDataSource() { let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { _, _, _ in } let textViewCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { [weak self] cell, _, _ in guard let self else { return } cell.contentView.addSubview(textView) textView.pin(to: cell.contentView.layoutMarginsGuide) } dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in if indexPath.row == 10 { collectionView.dequeueConfiguredReusableCell(using: textViewCellRegistration, for: indexPath, item: itemIdentifier) } else { collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier) } } var snapshot = NSDiffableDataSourceSnapshot<String, Int>() snapshot.appendSections(["section"]) snapshot.appendItems(Array(0...10)) dataSource.apply(snapshot) } } extension UIView { func pin( to object: CanBePinnedTo, top: CGFloat = 0, bottom: CGFloat = 0, leading: CGFloat = 0, trailing: CGFloat = 0 ) { self.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ self.topAnchor.constraint(equalTo: object.topAnchor, constant: top), self.bottomAnchor.constraint(equalTo: object.bottomAnchor, constant: bottom), self.leadingAnchor.constraint(equalTo: object.leadingAnchor, constant: leading), self.trailingAnchor.constraint(equalTo: object.trailingAnchor, constant: trailing), ]) } } @MainActor protocol CanBePinnedTo { var topAnchor: NSLayoutYAxisAnchor { get } var bottomAnchor: NSLayoutYAxisAnchor { get } var leadingAnchor: NSLayoutXAxisAnchor { get } var trailingAnchor: NSLayoutXAxisAnchor { get } } extension UIView: CanBePinnedTo { } extension UILayoutGuide: CanBePinnedTo { } How do I make the UI move to accomodate the keyboard once you tap on the text view and also when the text view changes size, by activating the view.keyboardLayoutGuide.topAnchor constraint, as shown in the WWDC21 video "Your guide to keyboard layout"? My code does not resize the text view on iOS 15, only on iOS 16+, so clearly the solution may allow the UI to adjust to text view changes on iOS 16+ only. Recommended, modern, approach: Not recommended, old, approach: I've tried to say view.keyboardLayoutGuide.topAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true in the text view cell registration, as well as view.keyboardLayoutGuide.topAnchor.constraint(equalTo: collectionView.bottomAnchor).isActive = true in viewDidLoad(), but both of these approaches fail (Xcode 15.3 iPhone 15 Pro simulator with iOS 17.4, physical iPhone SE on iOS 15.8).
Posted
by
Post marked as solved
1 Replies
68 Views
The following UIKit swift app uses a table view with 2 sections. The first section displays a custom cell with a text view, which was added to the cell’s contentView and anchored to the ladder’s layoutMarginsGuide’s top, bottom, leading and trailing anchors. The second section displays a custom cell that is like the former but with a text field instead of a text view. Both sections have titles defined in the tableView(_:cellForRowAt:) method. If you run the app, you will see that the text view’s text is not vertically aligned to it’s section’s title, whereas the text field’s is. How do I align the text view’s text as well? import UIKit class ViewController: UIViewController { let tableView = UITableView() override func viewDidLoad() { super.viewDidLoad() view.addSubview(tableView) tableView.frame = view.bounds tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] tableView.dataSource = self tableView.register(TextViewCell.self, forCellReuseIdentifier: TextViewCell.identifier) tableView.register(TextFieldCell.self, forCellReuseIdentifier: TextFieldCell.identifier) } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { 2 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.section == 0 { tableView.dequeueReusableCell(withIdentifier: TextViewCell.identifier, for: indexPath) } else { tableView.dequeueReusableCell(withIdentifier: TextFieldCell.identifier, for: indexPath) } } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { "Title \(section)" } } extension UITableViewCell { static var identifier: String { "\(Self.self)" } } class TextViewCell: UITableViewCell { let textView: UITextView = { let tv = UITextView() tv.text = "Text view" tv.font = .preferredFont(forTextStyle: .title2) tv.backgroundColor = .systemRed tv.isScrollEnabled = false return tv }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(textView) textView.pin(to: contentView.layoutMarginsGuide) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class TextFieldCell: UITableViewCell { let textField: UITextField = { let tf = UITextField() tf.text = "Text field" tf.backgroundColor = .systemBlue return tf }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(textField) textField.pin(to: contentView.layoutMarginsGuide) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } Here's how the pin(to:) function is defined in case you're wondering: import UIKit extension UIView { func pin( to object: CanBePinnedTo, top: CGFloat = 0, bottom: CGFloat = 0, leading: CGFloat = 0, trailing: CGFloat = 0 ) { self.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ self.topAnchor.constraint(equalTo: object.topAnchor, constant: top), self.bottomAnchor.constraint(equalTo: object.bottomAnchor, constant: bottom), self.leadingAnchor.constraint(equalTo: object.leadingAnchor, constant: leading), self.trailingAnchor.constraint(equalTo: object.trailingAnchor, constant: trailing), ]) } } @MainActor protocol CanBePinnedTo { var topAnchor: NSLayoutYAxisAnchor { get } var bottomAnchor: NSLayoutYAxisAnchor { get } var leadingAnchor: NSLayoutXAxisAnchor { get } var trailingAnchor: NSLayoutXAxisAnchor { get } } extension UIView: CanBePinnedTo { } extension UILayoutGuide: CanBePinnedTo { }
Posted
by
Post not yet marked as solved
0 Replies
86 Views
Hi everyone! Anyone else seeing crashes like this: Fatal Exception: NSInvalidArgumentException. -[_UISnapshotWindow actualSceneBounds]: unrecognized selector sent to instance I'm encountering a crash within 3-4 seconds of launching my iOS app specifically on devices running iOS 14. The crash log indicates an NSInvalidArgumentException with the following message: `Fatal Exception: NSInvalidArgumentException 0 CoreFoundation 0x129754 __exceptionPreprocess 1 libobjc.A.dylib 0x287a8 objc_exception_throw 2 CoreFoundation 0x2cc3c -[NSOrderedSet initWithSet:copyItems:] 3 UIKitCore 0xc01ea0 -[UIResponder doesNotRecognizeSelector:] 4 CoreFoundation 0x12c2ac ___forwarding___ 5 CoreFoundation 0x12e5b0 _CF_forwarding_prep_0 6 UIKitCore 0xa918cc -[UIUndoGestureInteraction didMoveToView:] 7 UIKitCore 0x11099b4 _setInteractionView 8 UIKitCore 0x11098bc -[UIView(Dragging) addInteraction:] 9 UIKitCore 0xe9d678 -[UIEditingOverlayViewController _addInteractions] 10 UIKitCore 0x4a73e4 -[UIViewController _setViewAppearState:isAnimating:] 11 UIKitCore 0x4a7910 __52-[UIViewController _setViewAppearState:isAnimating:]_block_invoke 12 CoreFoundation 0xa75bc __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ 13 CoreFoundation 0x2410 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] 14 UIKitCore 0x4a75ac -[UIViewController _setViewAppearState:isAnimating:] 15 UIKitCore 0x4a7dc0 -[UIViewController __viewDidAppear:] 16 UIKitCore 0x4a9964 __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke 17 UIKitCore 0x4a873c -[UIViewController _executeAfterAppearanceBlock] 18 UIKitCore 0xbda7c4 _runAfterCACommitDeferredBlocks 19 UIKitCore 0xbc903c _cleanUpAfterCAFlushAndRunDeferredBlocks 20 UIKitCore 0xbfcf10 _afterCACommitHandler 21 CoreFoundation 0xa25e0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ 22 CoreFoundation 0x9c704 __CFRunLoopDoObservers 23 CoreFoundation 0x9ccb0 __CFRunLoopRun 24 CoreFoundation 0x9c360 CFRunLoopRunSpecific 25 GraphicsServices 0x3734 GSEventRunModal 26 UIKitCore 0xbca584 -[UIApplication _run] 27 UIKitCore 0xbcfdf4 UIApplicationMain 28 JobLogic 0x1d9ac4 main + 14 (main.m:14) 29 libdyld.dylib 0x1cf8 start` Here's what I've observed: The crash consistently occurs within 3-4 seconds of app launch on iOS 14 devices. I'm seeking assistance with: Understanding the Cause: Any insights into potential causes of this crash, particularly related to _[_UISnapshotWindow actualSceneBounds] and its interaction with iOS 14, would be greatly appreciated. Replication Steps: If possible, guidance on how to reliably replicate the crash on a development device would be extremely helpful for debugging purposes. Solutions: Any suggestions or known workarounds to address this specific crash or similar issues in iOS 14 would be invaluable.
Posted
by
Post not yet marked as solved
0 Replies
42 Views
I tried to create the demo with the code import UIKit class ViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate { override func viewDidLoad() { super.viewDidLoad() self.browserUserInterfaceStyle = .dark let button = UIBarButtonItem(title: "First", style: .plain, target: nil, action: #selector(action(_:))) let button2 = UIBarButtonItem(title: "Second", style: .plain, target: nil, action: #selector(action(_:))) self.additionalLeadingNavigationBarButtonItems = [button, button2] } @objc func action(_ sender: UIBarButtonItem) { showAlert(with: sender) } func showAlert(with button: UIBarButtonItem) { let controller = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let action = UIAlertAction(title: "Test", style: .default) controller.addAction(action) controller.addAction(action) let presentationPopover = controller.popoverPresentationController presentationPopover?.sourceItem = button present(controller, animated: true) } } But the action sheet is in the wrong position when the user taps the button bar. This issue only happens when the user switches between the share and recent options before tapping the bar button.
Posted
by
Post not yet marked as solved
0 Replies
217 Views
Though I cannot find any documentation, it seems that UIPasteboard cannot be used from a Quick Look Preview app extension. I have such an extension, which contains a view that supports copying text as follows: - (IBAction)copy:(nullable id)sender { UIPasteboard * pboard = UIPasteboard.generalPasteboard; pboard.string = _rep.text; } This is invoked from a context menu (edit menu) item. This works fine In the simulator, but on device the pasteboard remains empty and errors like the following are emitted: -[PBServerConnection pasteboardWithName:createIfNeeded:authenticationBlock:dataOwnerBlock:error:] failed with error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.pasteboard.pasted was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.pasteboard.pasted was invalidated: failed at lookup with error 159 - Sandbox restriction.} It's unclear to me why such functionality would be problematic and necessary to block. It would be nice if this were documented clearly, as I wasted a lot of time trying to figure out why this was not working. (And no, I have not filed a feedback report or TSI yet, as I'm presently very short on time, and I don't have a sample project prepared to demonstrate the issue.)
Posted
by
Post not yet marked as solved
3 Replies
200 Views
hi I have been using WKWebView embedded in a UIViewRepresentable for displaying inside a SwiftUI View hierarchy, but when I try the same code on 17,5 beta (simulator) the code fails. In fact, the code runs (no exceptions raised or anything) but the web view does not render. In the console logs I see: Warning: -[BETextInput attributedMarkedText] is unimplemented Error launching process, description 'The operation couldn’t be completed. (OSStatus error -10814.)', reason '' The code I am using to present the view is: struct MyWebView: UIViewRepresentable { let content: String func makeUIView(context: Context) -> WKWebView { // Javascript that disables pinch-to-zoom by inserting the HTML viewport meta tag into <head> let source: String = """ var meta = document.createElement('meta'); meta.name = 'viewport'; meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'; var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = '*:focus{outline:none}body{margin:0;padding:0}'; var head = document.getElementsByTagName('head')[0]; head.appendChild(meta); head.appendChild(style); """ let script: WKUserScript = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true) let userContentController: WKUserContentController = WKUserContentController() let conf = WKWebViewConfiguration() conf.userContentController = userContentController userContentController.addUserScript(script) let webView = WKWebView(frame: CGRect.zero /*CGRect(x: 0, y: 0, width: 1000, height: 1000)*/, configuration: conf) webView.isOpaque = false webView.backgroundColor = UIColor.clear webView.scrollView.backgroundColor = UIColor.clear webView.scrollView.isScrollEnabled = false webView.scrollView.isMultipleTouchEnabled = false if #available(iOS 16.4, *) { webView.isInspectable = true } return webView } func updateUIView(_ webView: WKWebView, context: Context) { webView.loadHTMLString(content, baseURL: nil) } } This has been working for ages and ages (back to at least ios 15) - something changed. Maybe it is just a problem with the beta 17.5 release?
Posted
by
Post not yet marked as solved
0 Replies
71 Views
extension UIView { func takeSnapshot(rect : CGRect? = CGRect.zero) -&gt; UIImage? { let renderer = UIGraphicsImageRenderer(size: frame.size) var image = renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) } if let imageRect = rect, imageRect != CGRect.zero { let screenshotFrame = CGRect(x: imageRect.origin.x * UIScreen.main.scale, y: imageRect.origin.y * UIScreen.main.scale, width: imageRect.size.width * UIScreen.main.scale, height: imageRect.size.height * UIScreen.main.scale) let imageRef = image.cgImage!.cropping(to: screenshotFrame) image = UIImage.init(cgImage: imageRef!, scale: image.scale, orientation: image.imageOrientation) } UIGraphicsEndImageContext() return image } } which was working fine until I updated to macOS 14.4.1 from 14.2.1 and to Xcode 15.3 from 15.0. issue From my Mac Catalyst app, if I try to take screenshot of imageView, the screenshot is brighter. If I try this method it seems working: func takeSnapshotWithoutScale() -&gt; UIImage? { UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0) if let currentContext = UIGraphicsGetCurrentContext() { self.layer.render(in: currentContext) } let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage }
Posted
by
Post not yet marked as solved
1 Replies
114 Views
I'm trying to get voiceover to announce accessibility label for UIActivityViewController (for a share sheet that pops up on clicking share button) before the focus goes to one of activity items inside the UIActivityViewController. In order to achieve the above behavior, I'm just assigning accessibilityLabel for UIActivityViewController's view. But looks like I'm not able to override the default accessibility implementation of UIActivityViewController. Is there any way we could override the existing accessibility behavior of UIActivityViewController and announce accessibility label for share options? Thanks in advance!!
Posted
by
Post not yet marked as solved
1 Replies
119 Views
Hi all apple devs! I am a young developer who is completely new to everything programming. I am currently trying to develop an app where I want to use visionkit, but I can't for the life of me figure out how to implement its features. I've been stuck on this for several days, so I am now resorting to asking all of you experts for help! Your assistance would be immensely appreciated! I started to develop the app trying to exclusively use swiftUI to futureproof my app. Upon figuring out what visionkit is, to my understanding it is more compatible with UIkit? So I rewrote the part of my code that will use visionkit into a UIkit based view, to simplify the integration of visionkits features. It might just have overcomplicated my code? Can visionkit be easily implemented using only swiftUI? I noticed in the demo on the video tutorial the code is in a viewcontroller not a contentview, is this what makes my image unresponsive? My image is not interactable like her demo in the video, where in my code do I go wrong? Help a noob out! The desired user flow is like this: User selects an image through the "Open camera" or "Open Camera Roll" buttons. Upon selection the UIkit based view opens and the selected image is displayed on it. (This is where I want to implement visionkit features) User interacts with the image by touching on it, if touching on a subject, the subject should be lifted out of the rest of the image and be assigned to the editedImage, which in turn displays only the subject without the background on the contentview. (For now the image is assigned to editedimage by longpressing without any subjectlifting since I cant get visionkit to work as I want) Anyways, here's a code snippet of my peculiar effort to implement subject lifting and visionkit into my app:
Posted
by
Post marked as solved
1 Replies
143 Views
Hi, developers! I use DiffableDataSource for myTableView and was surprised when I found that TableView in this case caches previously created cells after (or before) a new update. It seems that this is implemented to store cell states and quickly update if the contents of the table change. Because of this mechanism, I have the following problem: my cells use reference-type view models, which in turn contain notification observers from the file upload service. The view model is connected to the cell with a closure, which is called upon notification and updates, for example, the progress scale in the cell After uploading the file, I make a new applySnapshot using similar models with cameras (but, for example, the "fileName" field is already different, so I need to change it in cell). Due to caching of cells in memory, the old view models with observers are not released, as a result, I get two observers, for two different cells, one of which is visible, and the second is not. This causes problems with UI. To summarize, my question is, is it possible to disable cell caching or clean the cache if using Diffable Data Source manually?
Posted
by
Post not yet marked as solved
1 Replies
139 Views
I need to create a carousel component with the following requirements (sorted by relevance): Objectives Every image is 16:9 aspect ratio and resizes to fit the screen. Needs a zoom and pan functionality, possibly the same way as iOS Photos app. Needs to work both in landscape and portrait mode, with a smooth transition between orientations. When orientation changes, the image needs to be rotated to preserve the center of the image (like Photos app and hyperoslo/Lightbox) The component should only take the minimum necessary space. In most use cases, such component should have other subviews both above and below. Circularity. I would like the carousel to wrap around. What I tried: Using a TabView with .tabViewStyle(PageTabViewStyle()).indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always)) modifiers. This didn't work: rotating the interface caused the view to get stuck between pages (it looks like it's a well known [bug]).(https://stackoverflow.com/questions/72435939/swiftui-tabview-is-not-working-properly-on-orientation-change). Implementing a single page (that is, an image view) using an UIScrollView and an UIViewRepresentable, then collecting them into an HStack. Unfortunately I need to use zoomScale and contentOffset properties of the UIScrollView outside of the UIViewRepresentable itself. The net result was that .init() was invoked for every image in the carousel at every rotation, causing severe stutters and an horrible rotation animation. Implementing the whole carousel using UIKit, and an UICollectionView, whose cells were an instance of UIScrollView. The problem is, the UIScrollView needs to recompute its constraints upon rotation but a cell is an instance of UIView, so it can't respond to rotations via viewWillTransition(to:CGSize, with: any UIViewControllerTransitionCoordinator). In the UICollectionView itself, you can only access the visible cells (one at a time is visible), and cells are cached, so even after rotating, some occasionally are presented on screen with the same appearance as before the rotation (some do, some don't, in the same UICollectionView). Also when rotating, it looks like the UIScrollView of the visible cell is being recreated, making it impossible to preserve the image center (I use this subclass of UIScrollView for this purpose). And the UICollectionView is taking the full window size, not just the bare minimum necessary space. Help: With all of this in mind, what options do I realistically have? If necessary I can raise the minimum iOS version to 16.0, even though I guess it doesn't make any significative difference since SwiftUI introduced MagnifyGesture only from iOS 17.0.
Posted
by
Post marked as solved
1 Replies
100 Views
Please run the following UIKit app. It displays a collection view with compositional layout (list layout) and diffable data source. import UIKit class ViewController: UIViewController { var bool = false { didSet { var snapshot = dataSource.snapshot() snapshot.reconfigureItems(snapshot.itemIdentifiers) dataSource.apply(snapshot, animatingDifferences: true) } } var collectionView: UICollectionView! var dataSource: UICollectionViewDiffableDataSource<String, String>! var snapshot: NSDiffableDataSourceSnapshot<String, String> { var snapshot = NSDiffableDataSourceSnapshot<String, String>() snapshot.appendSections(["section"]) snapshot.appendItems(["id"]) return snapshot } override func viewDidLoad() { super.viewDidLoad() configureHierarchy() configureDataSource() } func configureHierarchy() { collectionView = .init(frame: view.bounds, collectionViewLayout: createLayout()) view.addSubview(collectionView) collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] } func createLayout() -> UICollectionViewLayout { let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped) return UICollectionViewCompositionalLayout.list(using: configuration) } func configureDataSource() { let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { [weak self] cell, indexPath, itemIdentifier in guard let self else { return } let _switch = UISwitch() cell.accessories = [ .customView(configuration: .init( customView: _switch, placement: .trailing()) ), // .disclosureIndicator() ] _switch.isOn = bool _switch.addTarget(self, action: #selector(toggleBool), for: .valueChanged) } dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier) } dataSource.apply(self.snapshot, animatingDifferences: false) } @objc func toggleBool() { bool.toggle() } } When you tap on the switch, it lags. If you uncomment .disclosureIndicator() and tap on the switch, it doesn't lag. How do I make it so that the switch doesn't lag without having a disclosure indicator in the cell? Note: while it would solve the issue, I would prefer not to declare the switch at the class level, as I don't want to declare all my controls, which could be quite a lot, at the view controller level in my real app. Edit: declaring the switch at the configureDataSource() level also fixes it, but it would still be inconvenient to declare many switches, say of a list with n elements, at that level.
Posted
by
Post marked as solved
6 Replies
153 Views
Hi together, i have truble to parse an json with an array like following: "data": [ [ 0000000000, [ { "count": 0 } ] ], [ 0000000000, [ { "count": 0 } ] ] ], Can someone help me to parse that with the this? Thanks
Posted
by
Post marked as Apple Recommended
174 Views
How can I open the user's Health Privacy Settings directly from my app when I'd like them to review them? I believe similar questions have been asked before like this one: https://forums.developer.apple.com/forums/thread/730434 However, I'm wondering if the situation is changed for iOS 17 or if there's a way that works for Health permissions. This is directly possible in the Garmin Connect app for example which is a major app on the store.
Posted
by
Post not yet marked as solved
1 Replies
125 Views
Hello, Is there any way to iterate all views and subviews in current xcode app and taget to particular properties to every UIButton. I tried using folllowing code but it is not working. for views in self.view.subviews { if views == UIButton { button.isPointerInteractionEnabled = true } else { } }
Posted
by
Post not yet marked as solved
0 Replies
150 Views
First of all, I decided to make my project with only UIKit. So I deleted 'Main' storyboard, Info.plist->Storyboard name, and Main storyboard file base name->Main. And I edited SceneDelegate. So now I can display the single viewControllers, but when I try to set 'UITabBarController' to rootViewController, It cause this error(title). I tried to make UITabBarController in ViewController, UITabBarController in SceneDelegate and some more. // BackgroundViewController for the rootViewController import UIKit class BackgroundViewController: UIViewController { let backgroundTabBarController = UITabBarController() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white createTabBar() } } extension BackgroundViewController { private func createTabBar() { view.backgroundColor = .white view.addSubview(backgroundTabBarController.view) let firstViewController = BookSearchViewController() let secondViewController = MainViewController() let thirdViewController = UserStatusViewController() let lastViewController = OrderViewController() firstViewController.tabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass.circle.fill"), selectedImage: UIImage(systemName: "magnifyingglass.circle")) secondViewController.tabBarItem = UITabBarItem(title: "Main", image: UIImage(systemName: "house.fill"), selectedImage: UIImage(systemName: "house")) thirdViewController.tabBarItem = UITabBarItem(title: "My", image: UIImage(systemName: "person.fill"), selectedImage: UIImage(systemName: "person")) lastViewController.tabBarItem = UITabBarItem(title: "Order", image: UIImage(systemName: "menucard.fill"), selectedImage: UIImage(systemName: "menucard")) backgroundTabBarController.viewControllers = [firstViewController, secondViewController, thirdViewController, lastViewController] backgroundTabBarController.selectedViewController = secondViewController } } // SceneDelegate import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) window?.rootViewController = BackgroundViewController() window?.makeKeyAndVisible() } } // Error code Thread 1: "Could not find a storyboard named 'Main' in bundle NSBundle </Users/[MyDesktopName]/Library/Developer/CoreSimulator/Devices/[ApplicationName]/data/Containers/Bundle/Application/[ApplicationName]/BTY.app> (loaded)" But anyone of this solve the problem. How can I make UITabBarController to rootViewController? Make UITabBarController in SceneDelegate Make new UIViewController that have UITabBarController and set to rootViewController Set ViewControllers with 'UINavigationController(rootViewController:)' Present UITabBarController from other viewController
Posted
by
Post not yet marked as solved
0 Replies
156 Views
First of all, I decided to make my project with only UIKit. So I deleted 'Main' storyboard, Info.plist->Storyboard name, and Main storyboard file base name->Main. And I edited SceneDelegate. So now I can display the single viewControllers, but when I try to set 'UITabBarController' to rootViewController, It cause this error(title). I tried to make UITabBarController in ViewController, UITabBarController in SceneDelegate and some more. How can I fix this? We can't use code-based UITabBarController in new version of Xcode now?
Posted
by
Post not yet marked as solved
0 Replies
118 Views
I'm using something similar to this example. import SwiftUI struct ContentView: View { @State private var toggle = false var body: some View { CustomParentView { Button { toggle.toggle() } label: { Text(toggle.description) } } } } struct CustomParentView<Content: View>: UIViewRepresentable { let content: Content @inlinable init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIView(context: Context) -> UIView { let view = UIView() let hostingController = context.coordinator.hostingController hostingController.view.frame = view.bounds hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(hostingController.view) return view } func updateUIView(_ uiView: UIView, context: Context) { context.coordinator.hostingController.rootView = self.content } class Coordinator: NSObject { var hostingController: UIHostingController<Content> init(hostingController: UIHostingController<Content>) { self.hostingController = hostingController } } func makeCoordinator() -> Coordinator { return Coordinator(hostingController: UIHostingController(rootView: content)) } } The only different thing is I'm using UIScrollView. When I have a @State width and call .frame(width) on the content, the content would stay with initial width even when width is changed. I tried: hostingController.sizingOptions = .intrinsicContentSize This time the size would change to correct size if I pinch zoom the content, but the initial size that trigger updateUIView would be .zero. This prevents me to center the content. Is there a way to dynamically set size and get correct rendering just like any child view of a normal SwiftUI view?
Posted
by
Post not yet marked as solved
0 Replies
144 Views
It's been a really long time since I've tried this, so I'm not sure if something has changed or if I've stumbled onto a bug... I'm trying to implement a custom Transition Animation for a UINavigationController. While documentation around this is pretty sparse this days, I was able to take the old sample from the View Controller Programming Guide:, rewriting it in Swift: func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to), let toView = transitionContext.view(forKey: .to), let fromView = transitionContext.view(forKey: .from) else { transitionContext.completeTransition(false) return } let containerFrame = containerView.frame var toViewStartFrame = transitionContext.initialFrame(for: toVC) let toViewFinalFrame = transitionContext.finalFrame(for: toVC) var fromViewFinalFrame = transitionContext.finalFrame(for: fromVC) let fromViewStartFrame = transitionContext.initialFrame(for: fromVC) if operation.isPresenting { toViewStartFrame.origin.x = containerFrame.size.width toViewStartFrame.origin.y = containerFrame.size.height } else { fromViewFinalFrame = CGRect(x: containerFrame.size.width, y: containerFrame.size.height, width: toView.frame.size.width, height: toView.frame.size.height) // missing from Apple's sample code toViewStartFrame = toViewFinalFrame } containerView.addSubview(toView) toView.frame = toViewStartFrame // Add the from view to the container view on dismissal, this is missing from Apple's sample code if !operation.isPresenting { containerView.addSubview(fromView) fromView.frame = fromViewStartFrame } UIView.animate(withDuration: transitionDuration(using: transitionContext)) { if self.operation.isPresenting { toView.frame = toViewFinalFrame } else { fromView.frame = fromViewFinalFrame } } completion: { completed in let success = !transitionContext.transitionWasCancelled if (self.operation.isPresenting && !success) || (!self.operation.isPresenting && success) { toView.removeFromSuperview() } // missing from Apple's sample code if !self.operation.isPresenting { fromView.removeFromSuperview() } transitionContext.completeTransition(success) } } I added a couple of things to support dismissals and pops. In order to use it with in my app, I set the navigation controller's delegate and returned the type conforming to UIViewControllerAnimatedTransitioning, containing the above code, from navigationController(_ :, animationControllerFor operation:, from fromVC:, to toVC). I've confirmed that that all behaves as you expect. If I use this animation controller for a modal presentation or dismissal, it works fine. For a Navigation push, again, behaves as expected. But when I use it for a navigation pop I run into a problem. The animation is performed, but once it completes, the Navigation Controller's view appears to be completely empty. In a sample app, the screen goes black. In the View Debugger, I see that the UIViewControllerWrapperView has no subviews. Another curious thing I found is that my View Controller never gets a viewWillDisappear message sent. Is there an additional setup step that I missed in order to get this working properly?
Posted
by