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

UIKit Documentation

Posts under UIKit tag

713 Posts
Sort by:
Post not yet marked as solved
0 Replies
29 Views
Preface Upon rotating the interface, the UICollectionViewCells overlap, generating an unpleasant animation that for sure can't be used in production. The code The code was executed on iPhone 6S (NN0W2TU/A A1688) with iOS 15.8.2. I could reproduce the issue on iPhone 15 Pro with iOS 17 on simulator as well. SelfConfiguringCell.swift: import UIKit protocol SelfConfiguringCell: UICollectionViewCell { static var reuseIdentifier: String { get } func configure(with image: String) } ISVImageScrollView.swift: Code here CarouselCell.swift: import UIKit import SnapKit class CarouselCell: UICollectionViewCell, SelfConfiguringCell, UIScrollViewDelegate { static var reuseIdentifier: String = "carousel.cell" internal var image: String = "placeholder" { didSet { self.imageView = UIImageView(image: UIImage(named: image)) self.scrollView.imageView = self.imageView } } let scrollView: ISVImageScrollView = { let scrollView = ISVImageScrollView() scrollView.minimumZoomScale = 1.0 scrollView.maximumZoomScale = 30.0 scrollView.zoomScale = 1.0 scrollView.contentOffset = .zero scrollView.bouncesZoom = true return scrollView }() var imageView: UIImageView = { let image = UIImage(named: "placeholder")! let imageView = UIImageView(image: image) return imageView }() func setImage(_ image: String) { self.image = image } func configure(with image: String) { self.setImage(image) self.scrollView.snp.makeConstraints { make in make.left.top.right.bottom.equalTo(contentView) } } override init(frame: CGRect) { super.init(frame: frame) contentView.backgroundColor = UIColor.black scrollView.delegate = self scrollView.imageView = self.imageView contentView.addSubview(scrollView) } required init?(coder: NSCoder) { fatalError("Cannot init from storyboard") } func viewForZooming(in scrollView: UIScrollView) -> UIView? { return self.imageView } } ViewController: import UIKit class ViewController: UICollectionViewController { var currentPage: IndexPath? = nil let images = ["police", "shutters", "depot", "cakes", "sign"] init() { let compositionalLayout = UICollectionViewCompositionalLayout { sectionIndex, environment in let absoluteW = environment.container.effectiveContentSize.width let absoluteH = environment.container.effectiveContentSize.height // Handle landscape if absoluteW > absoluteH { print("landscape") let itemSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1) ) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1) ) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) return section } else { // Handle portrait print("portrait") let itemSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(absoluteW * 9.0/16.0) ) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(absoluteW * 9.0/16.0) ) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) return section } } let config = UICollectionViewCompositionalLayoutConfiguration() config.interSectionSpacing = 0 config.scrollDirection = .horizontal compositionalLayout.configuration = config super.init(collectionViewLayout: compositionalLayout) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() collectionView.delegate = self collectionView.dataSource = self collectionView.isPagingEnabled = true // Register cell for reuse collectionView.register(CarouselCell.self, forCellWithReuseIdentifier: CarouselCell.reuseIdentifier) } override func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.images.count } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let reusableCell = collectionView.dequeueReusableCell(withReuseIdentifier: CarouselCell.reuseIdentifier, for: indexPath) as? CarouselCell else { fatalError() } let index : Int = (indexPath.section * self.images.count) + indexPath.row reusableCell.configure(with: self.images[index]) return reusableCell } } Notes I found a similar unanswered question here. I'm sure something can be done about it because if I switch to SwiftUI with a TabView, that according to SwiftUI Introspect documentation for TabViewWithPageStyleType, is using UICollectionView under the hood, I'm not getting that ugly animation anymore. Though I can't switch to SwiftUI to use TabView because on interface rotation it loses the page index (well known bug, see here), which probably is even trickier to workaround.
Posted Last updated
.
Post not yet marked as solved
0 Replies
48 Views
I am trying to save data files between runs of an iOS App from Xcode on a real iPad (not the simulator). NSHomeDirectory gives me a different directory every time I run the app on the iPad (from XCode). I cannot write a file on one run and then retrieve it on the next run. How do I get around this annoying problem?
Posted
by rmc0917.
Last updated
.
Post not yet marked as solved
0 Replies
58 Views
I have a UITableView with 1 section and 3 rows, and each row is 1000 height, the UITableView height is 832, such as below: but when I click the right button, the visibleCells has 2 items(row-0 and row-1), but the indexPathsForVisibleRows only has 1 item(row-0). In my expectation, I set UITableView contentOffset with 168.8, the row-1 cell is visible. but indexPathsForVisibleRows does not correct. Well then, I try to read the assembly of indexPathsForVisibleRows, I found that the UITableView use _visibleBounds to compute indexPathsForVisibleRows, but the _visibleBounds.height is reduced by one when compute, why? the assembly code looks like below:
Posted
by PingHst.
Last updated
.
Post not yet marked as solved
0 Replies
111 Views
I'm creating a slate pad for Ipad with several input fields to fill using Adobe XD. How can I obtain and attach a virtual keyboard to fill these input fields? I found a video with a similar concept but on Iphone: https://www.youtube.com/watch?v=O7tPI0VuKd4&list=PLWeIX-zcNnqII-nzviv_yxT2WNQRRYbiG&index=3 In this other link, the video mentions that the virtual keyboard was obtained from a UI kit that Apple provides. But I've looked and looked and I can't find a page to download this virtual keyboard. Any ideas? https://www.youtube.com/watch?v=rosf7-zVYjY&t=122s
Posted Last updated
.
Post not yet marked as solved
2 Replies
267 Views
I have created a custom input field by conforming to UITextInput. It is setup to use UITextInteraction. Everything works very well. If the user taps on the custom field, the cursor (provided by UITextInteraction) appears. The user can type, select, move the cursor, etc. But I'm stumped trying to get the cursor to appear automatically. With a normal UITextField or UITextView you simply call becomeFirstResponder(). But doing that with my custom UITextInput does not result in the cursor appearing. It only appears if the user taps on the custom field. I don't know what I'm missing. I don't see any API in UITextInteraction that can be called to say "activate the cursor layer". Does anyone know what steps are required with a custom UITextInput using UITextInteraction to activate the cursor programmatically without the user needing to tap on the custom field?
Posted
by RickMaddy.
Last updated
.
Post not yet marked as solved
0 Replies
46 Views
When I use "[[UIApplication sharedApplication] setAlternateIconName:iconId completionHandler:nil];" to change the icon, the following exception is thrown. Please tell me how to deal with this problem Error Domain=NSOSStatusErrorDomain Code=-54 "(null)" UserInfo={_LSLine=66,_LSFunction=-[_LSDIconCliend setAlternateIconName:forIdentifier:iconsDictionary:reply:]}
Posted
by teslamask.
Last updated
.
Post not yet marked as solved
1 Replies
73 Views
Hi, I have a UIBarButtonItem that I create with a UIMenu, and it's added to the navigation bar: self.rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd menu: [self createMenuForAddItem]]; self.navigationItem.rightBarButtonItems = @[self.rightButton]; The menu shows fine when a user clicks on the bar button. Now I want to also show this menu programmatically, for e.g if the user opens the app for the 5th time, the menu from the bar button item shows automatically, without the user having to explicitly press the button. How do I achieve this?
Posted
by zulfishah.
Last updated
.
Post not yet marked as solved
0 Replies
62 Views
I have a data object that dynamically changes the UIImage assigned to one of its instance variables, but when showing this image in SwiftUI, it's always black and white. The following sample code shows the difference between the same image, but using first the native constructor Image(systemName:) and then Image(uiImage:). When using AppKit and Image(nsImage:) this issue doesn't happen. import SwiftUI import UIKit struct ContentView: View { @State var object = MyObject() var body: some View { Image(systemName: "exclamationmark.triangle.fill") .symbolRenderingMode(.palette) .foregroundStyle(.white, .yellow) Image(uiImage: object.image) } } class MyObject { var image = UIImage(systemName: "exclamationmark.triangle.fill")! .applyingSymbolConfiguration(.init(paletteColors: [.white, .systemYellow]))! } #Preview { ContentView() }
Posted
by Nickkk.
Last updated
.
Post not yet marked as solved
1 Replies
72 Views
If I use UIEditMenuInteraction to present an edit menu, it has a dismissMenu method that I can call to remove the menu when necessary. When I use UITextInteraction, I get an edit menu automatically that is normally presented and dismissed at appropriate times. But sometimes I want to dismiss the menu myself, and I can't find a way to do that. Am I missing something? I was hoping to find that UITextInteraction inherited from UIEditMenuInteraction, or had some other way to access the underlying menu in order to dismiss it. But it seems that the menu must be a private part of the UITextInteraction implementation. The particular case that I need to deal with is when I call resignFirstResponder. This seems to cause the keyboard to close and the insertion point and any selection to be hidden, but if an edit menu was shown then it remains visible (a ghost!). If anyone knows of an alternative to resignFirstResponder that will make UITextInteraction tidy up properly, that would also be useful to know. Thanks for any suggestions!
Posted
by endecotp.
Last updated
.
Post not yet marked as solved
5 Replies
555 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 Last updated
.
Post marked as solved
2 Replies
140 Views
Summary Hello Apple Developers, I've made a custom UITableViewCell that includes a UITextField and UILabel. When I run the simulation the UITableViewCells pop up with the UILabel and the UITextField, but the UITextField isn't clickable so the user can't enter information. Please help me figure out the problem. Thank You! Sampson What I want: What I have: Screenshot Details: As you can see when I tap on the cell the UITextField isn't selected. I even added placeholder text to the UITextField to see if I am selecting the UITextField and the keyboard just isn't popping up, but still nothing. Relevant Code: UHTextField import UIKit class UHTextField: UITextField { override init(frame: CGRect) { super.init(frame: frame) configure() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } convenience init(placeholder: String) { self.init(frame: .zero) self.placeholder = placeholder } private func configure() { translatesAutoresizingMaskIntoConstraints = false borderStyle = .none textColor = .label tintColor = .blue textAlignment = .left font = UIFont.preferredFont(forTextStyle: .body) adjustsFontSizeToFitWidth = true minimumFontSize = 12 backgroundColor = .tertiarySystemBackground autocorrectionType = .no } } UHTableTextFieldCell import UIKit class UHTableTextFieldCell: UITableViewCell, UITextFieldDelegate { static let reuseID = "TextFieldCell" let titleLabel = UHTitleLabel(textAlignment: .center, fontSize: 16, textColor: .label) let tableTextField = UHTextField() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) configure() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func set(title: String) { titleLabel.text = title tableTextField.placeholder = "Enter " + title } private func configure() { addSubviews(titleLabel, tableTextField) let padding: CGFloat = 12 NSLayoutConstraint.activate([ titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor), titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding), titleLabel.heightAnchor.constraint(equalToConstant: 20), titleLabel.widthAnchor.constraint(equalToConstant: 80), tableTextField.centerYAnchor.constraint(equalTo: centerYAnchor), tableTextField.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 24), tableTextField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding), tableTextField.heightAnchor.constraint(equalToConstant: 20) ]) } } LoginViewController class LoginViewController: UIViewController, UITextFieldDelegate { let tableView = UITableView() let loginTableTitle = ["Username", "Password"] override func viewDidLoad() { super.viewDidLoad() configureTableView() updateUI() createDismissKeyboardTapGesture() } func createDismissKeyboardTapGesture() { // create the tap gesture recognizer let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing)) // add it to the view (Could also add this to an image or anything) view.addGestureRecognizer(tap) } func configureTableView() { view.addSubview(tableView) tableView.layer.borderWidth = 1 tableView.layer.borderColor = UIColor.systemBackground.cgColor tableView.layer.cornerRadius = 10 tableView.clipsToBounds = true tableView.rowHeight = 44 tableView.delegate = self tableView.dataSource = self tableView.translatesAutoresizingMaskIntoConstraints = false tableView.removeExcessCells() NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: loginTitleLabel.bottomAnchor, constant: padding), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding), tableView.heightAnchor.constraint(equalToConstant: 88) ]) tableView.register(UHTableTextFieldCell.self, forCellReuseIdentifier: UHTableTextFieldCell.reuseID) } func updateUI() { DispatchQueue.main.async { self.tableView.reloadData() self.view.bringSubviewToFront(self.tableView) } } } extension LoginViewController: UITableViewDelegate, UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: UHTableTextFieldCell.reuseID, for: indexPath) as! UHTableTextFieldCell let titles = loginTableTitle[indexPath.row] cell.set(title: titles) cell.titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold) cell.tableTextField.delegate = self return cell } } Again thank you all so much for your help. If you need more clarification on this let me know.
Posted Last updated
.
Post not yet marked as solved
1 Replies
139 Views
I wonder if an Apple engineer could confirm: will the Apple Pencil Pro squeeze functionality be detectable in the current API, or will this be a future iPadOS extension to gesture recognizers / UIKit? I’d like to start playing with the functionality if it’s detected behind an existing event though. (Long press?)
Posted Last updated
.
Post not yet marked as solved
0 Replies
85 Views
Our current status is that after three minutes or more in the background, re-opening the app is a restart. Most of the users are claiming that they were automatically redirected to the home page of our app after a certain period of inactivity in the app. I recently upgraded my Xcode version from 12.4 to 15.3. I did not experience the problem with Xcode 12.4. It is an enterprise application, and the majority of users report restart issues. It occurred at random, and the user device contained only our application, with no other app like entertainment or gaming apps. However, I notice that many other apps are running in the background for an extended period of time (such as 20 minutes or 30 minutes). When I open the app, the same page sometimes appears in the background or the app is refreshed (like, Medium) I am not sure how they do it; I follow Apple. The rules did not do anything after entering the background. Is there anything Apple could do? How can I resolve this issue? Or it is default iOS behaviour. Please provide any documentation related to this. Please help me resolve this issue. Note: iOS device Version 15 to 17 is the latest
Posted Last updated
.
Post not yet marked as solved
0 Replies
211 Views
Our keyboard extension can be accessed independently in China region with native app like Notes or Safari, however the keyboard can only be opened in the app under same project in Taiwan region. I've checked some articles about how MDM managing extensions, also make sure our RequestOpenAccess option of keyboard extension info.plist also set to Yes. I'm not sure is there anything I missed, or I just need to inform client that they need to reach out their MDM manager and modify some restrictions? If keyboard supports mobile device management (MDM), it can work with managed apps. App extensions give third-party developers a way to provide functionality to other apps or even to key systems built into the operating systems Allow full access to custom keyboard in iOS
Posted
by Rimbaud.
Last updated
.
Post not yet marked as solved
0 Replies
104 Views
Per the apple API documentation (https://developer.apple.com/documentation/tipkit/tipuipopoverviewcontroller/imagesize), imageSize is meant to control the size of the image within the tip, but it doesn't seem to be working. My code is as follows, taken from the apple docs example: tipObservationTask = tipObservationTask ?? Task { @MainActor [weak controller] in for await shouldDisplay in tip.shouldDisplayUpdates { if shouldDisplay { let popoverController = TipUIPopoverViewController(tip, sourceItem: sourceItem) popoverController.imageSize = CGSize(width: 10, height: 10) controller?.present(popoverController, animated: true) tipPopoverController = popoverController } else { if controller?.presentedViewController is TipUIPopoverViewController { controller?.dismiss(animated: true) tipPopoverController = nil } } } }
Posted
by L4D.
Last updated
.
Post marked as solved
1 Replies
85 Views
I can't fit the post here, so here's the link to it on stack overflow: https://stackoverflow.com/questions/78419812/reconfigure-custom-content-configuration
Posted
by Filippo02.
Last updated
.
Post not yet marked as solved
0 Replies
84 Views
This is a bug I have been trying to identify and fix for more than 3 weeks. This bug mostly happens in production. The stack trace doesn't help that much, because it looks like the app is crashing due to some SwiftUI internal methods. I tried everything in my power to debug and find this bug, still nothing. Due to the lack of 100% reproducibility, it made me think that this bug is either memory-pressure related or Swift concurrency related. When does it happen: This bug happens when presenting a SwiftUI modal (UIViewControllerRepresentable)[A] which in terms presents a UIHostingController modal[B] which then presents a modally a SwiftUI sheet [C] The bug happens somewhere around staying in [C] or after dismissing it. Context: The app lifecycle is SwiftUI. The main SwiftUI screen in the app body is a UIViewControllerRepresentable containing a UISplitViewController. Here is a screenshot from the crash log in Xcode. Anyone facing a similar issue?
Posted Last updated
.
Post not yet marked as solved
3 Replies
156 Views
Hi, do you guys have any idea why this code block doesn't run properly on a designed iPad app running on a vision pro simulator? I'm trying to add a hovering effect to a view in UIKit but it just doesn't enter this if statement. if #available(iOS 17.0, visionOS 1.0, *) { someView.hoverStyle = .init(effect: .automatic) }
Posted Last updated
.
Post not yet marked as solved
0 Replies
86 Views
I have a custom rotor that changes the skim speed of the skim forward/backward feature of my audio player. The rotor works, but it's always playing an end-of-list sound. Here is the code: // Member variables private let accessibilitySeekSpeeds: [Double] = [10, 30, 60, 180] // seconds private var accessibilitySeekSpeedIndex: Int = 0 func seekSpeedRotor() -> UIAccessibilityCustomRotor { UIAccessibilityCustomRotor(name: "seek speed") { [weak self] predicate in guard let self = self else { return nil } let speeds = accessibilitySeekSpeeds switch predicate.searchDirection { case .previous: accessibilitySeekSpeedIndex = (accessibilitySeekSpeedIndex - 1 + speeds.count) % speeds.count case .next: accessibilitySeekSpeedIndex = (accessibilitySeekSpeedIndex + 1) % speeds.count @unknown default: break } // Return the currently selected speed as an accessibility element let accessibilityElement = UIAccessibilityElement(accessibilityContainer: self) let currentSpeed = localizedDuration(seconds: speeds[accessibilitySeekSpeedIndex]) accessibilityElement.accessibilityLabel = currentSpeed + " seek speed" UIAccessibility.post(notification: .announcement, argument: currentSpeed + " seek speed") return UIAccessibilityCustomRotorItemResult(targetElement: accessibilityElement, targetRange: nil) } } The returned accessibility element isn't read out, and instead an end-of-list sound is played. I can announce the change manually using UIAccessibility.post, but it still plays the end-of-list sound. How can I prevent the rotor from playing the end-of-list sound?
Posted Last updated
.
Post not yet marked as solved
0 Replies
100 Views
I am getting this error, only in iOS 17 (all version) on old code that had been working since iOS 15. The error occurs whenever the collectionView need to increase it's height beyond its initial height. The collectionView is inside a tableView. All autolayout constraints are set and everything use to work fine in previous version of iOS. *** Assertion failure in -[MYAPP.MYCollectionView _updateLayoutAttributesForExistingVisibleViewsFadingForBoundsChange:], UICollectionView.m:6218
Posted
by 2018code.
Last updated
.