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

UIKit Documentation

Posts under UIKit tag

1,022 Posts
Sort by:
Post not yet marked as solved
1 Replies
193 Views
Hi, I noticed a bug on UILabel only on iOS 15.4. If we have a UILabel with numberOfLines = 3 using byTruncatingHead and the text contains a \n, the last line replicates some characters from the previous line. Please take a look at the attached screenshot. The code is very simple: var text = "A Person Name\nalso commented on Other Person\'s post: Hi Eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" label.text = text label.numberOfLines = 3 label.lineBreakMode = .byTruncatingHead Note: UILabel has 32 horizontal margin constraints and I tested it on iPhone 12. I tested it on iPhone 11 running iOS 15.3 and it works fine.
Posted
by rbusatact.
Last updated
.
Post not yet marked as solved
1 Replies
124 Views
Hi, I noticed a bug on UILabel only on iOS 15.4. If we have a UILabel with numberOfLines = 3 using byTruncatingHead and the text contains a \n, the last line replicates some characters from the previous line. Please take a look at the attached screenshot. The code is very simple: var text = "A Person Name\nalso commented on Other Person\'s post: Hi Eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" label.text = text label.numberOfLines = 3 label.lineBreakMode = .byTruncatingHead Note: UILabel has 32 horizontal margin constraints and I tested it on iPhone 12. I tested it on iPhone 11 running iOS 15.3 and it works fine. Regards, Rodrigo Busata
Posted
by rbusatact.
Last updated
.
Post not yet marked as solved
2 Replies
936 Views
I've created a new Xcode project and I added a new Custom Keyboard Extension Target by using Editor > Add Target > Custom Keyboard Extension.Then, I ran that default templated keyboard on my real device (not happened in simulator). And I opened Instruments > Allocations application to profile memory allocations of extension.When I was trying the keyboard on WhatsApp, I've noticed that number of Persistent ViewController objects were increased while hide/unhide the keyboard by tap on the outside of the keyboard and tap input area.Number of Persistent KeyboardViewController:2 -- hide -- > 1 -- show -- > 3 -- hide --> 2 -- show --> 4 (increasing)I was trying the keyboard on iOS Messages app too. And there was no duplication.1 -- hide --> 0 -- show --> 1 -- hide --> 0 ( its ok )Do u have any idea about this issue ? Why WhatsApp application duplicates the keyboard extension viewController.
Posted
by emreyasar.
Last updated
.
Post not yet marked as solved
0 Replies
53 Views
My app used to rely on standard iOS Numpad Keyboard as a textField.inputView. The textField could group typed numbers (1000 -> 1 000, 50067 -> 50 067 etc) and limit the amount of numbers after the decimal point as 2 max: https://i.stack.imgur.com/69LVr.gif (GIF) I've created a custom numpad keyboard view and implement its logic with UITextInput protocol according to that guide on StackOverflow. I can't understand of how to deal with the code I used for grouping and limit numbers with standard iOS Numpad. Because it doesn't work properly after I type numbers from my new custom Numpad (only 2 numbers): https://i.stack.imgur.com/f3u3n.gif (GIF) The code I use for grouping and limit numbers after decimal point in a textField: func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.groupingSeparator = " " formatter.maximumFractionDigits = 2 let textString = textField.text ?? "" guard let range = Range(range, in: string) else { return false } let updatedString = textString.replacingCharacters(in: range, with: string) let correctDecimalString = updatedString.replacingOccurrences(of: ",", with: ".") let completeString = correctDecimalString.replacingOccurrences(of: formatter.groupingSeparator, with: "") guard completeString.count <= 12 else { return false } guard !completeString.isEmpty else { return true } textField.text = completeString return string == formatter.decimalSeparator } Custom NumpadView: class NumpadView: UIView { var target: UITextInput? init(target: UITextInput) { super.init(frame: .zero) self.target = target initializeSubview() } required init?(coder: NSCoder) { super.init(coder: coder) initializeSubview() } func initializeSubview() { let xibFileName = "NumpadView" let view = Bundle.main.loadNibNamed(xibFileName, owner: self, options: nil)![0] as! UIView self.addSubview(view) view.frame = self.bounds self.autoresizingMask = [.flexibleWidth, .flexibleHeight] } @IBAction func buttonPressed(_ sender: NumpadButton) { insertText((sender.titleLabel!.text)!) } func insertText(_ string: String) { guard let range = target?.selectedRange else { return } if let textField = target as? UITextField, textField.delegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == false { return } target?.insertText(string) } } extension UITextInput { var selectedRange: NSRange? { guard let selectedRange = selectedTextRange else { return nil } let location = offset(from: beginningOfDocument, to: selectedRange.start) let length = offset(from: selectedRange.start, to: selectedRange.end) return NSRange(location: location, length: length) } } 2.How I initialize it in a VC: override func viewDidLoad() { super.viewDidLoad() textField.delegate = self textField.inputView = NumpadView(target: textField) } Test project on GitHub: CLICK What should I do so the code in shouldChangeCharactersIn method work for my custom Numpad?
Posted Last updated
.
Post marked as solved
4 Replies
1.6k Views
I try to exclude some activities from UIActivity. It works as expected when exclusion is done directly with the activity, as with: UIActivity.ActivityType.message, UIActivity.ActivityType.airDrop but not when activity is declared with an init as with: UIActivity.ActivityType(rawValue: "net.whatsapp.WhatsApp.ShareExtension"), UIActivity.ActivityType(rawValue: "com.ifttt.ifttt.share"), So, with the following code: let excludedActivityTypes = [ UIActivity.ActivityType.message, UIActivity.ActivityType.airDrop, UIActivity.ActivityType(rawValue: "net.whatsapp.WhatsApp.ShareExtension"), UIActivity.ActivityType(rawValue: "com.ifttt.ifttt.share") ]         let activityVC = UIActivityViewController(activityItems: [modifiedPdfURL], applicationActivities: nil)          activityVC.excludedActivityTypes = excludedActivityTypes message and airDrop do not show, but WhatsApp and IFTTT still show. I have tested with         activityVC.completionWithItemsHandler = { (activity, success, modifiedItems, error) in             print("activity: \(activity), success: \(success), items: \(modifiedItems), error: \(error)")         } that WhatsApp and IFTTT services are effectively the ones listed here. When selecting WhatsApp, print above gives: activity: Optional(__C.UIActivityType(_rawValue: net.whatsapp.WhatsApp.ShareExtension)), success: false, items: nil, error: nil
Posted
by Claude31.
Last updated
.
Post not yet marked as solved
7 Replies
99 Views
Hi! My app is showing a rare crashes that I am not able to reproduce. The stack trace starts with lines like the following: 0 MyApp 0x00000001028edf38 function signature specialization <Arg[0] = Dead> of MyApp.CollectionViewDataSource.collectionView(_: __C.UICollectionView, didSelectItemAt: Foundation.IndexPath) -> () (<compiler-generated>:0) 1 MyApp 0x00000001028ed258 @objc MyApp.CollectionViewDataSource.collectionView(_: __C.UICollectionView, didSelectItemAt: Foundation.IndexPath) -> () (<compiler-generated>:0) 2 UIKitCore 0x00000001a4fd806c -[UICollectionView _selectItemAtIndexPath:animated:scrollPosition:notifyDelegate:deselectPrevious:performCustomSelectionAction:] + 1020 3 UIKitCore 0x00000001a536effc -[UICollectionView touchesEnded:withEvent:] + 612 … What does Arg[0] = Dead actually mean and what could I do to avoid this crash?
Posted Last updated
.
Post marked as solved
4 Replies
320 Views
Hi guys Has anybody hit any issues with the Navigation bar and tab bars being in the safe area. With ios16 the navigation bar appears onto of the status bar (in the safe area), the tab bar is also in the safe area. However, putting the device into landscape and then portrait brings it back closer (although the buttons no longer have an indentation). In the screenshot on the left is how the app is first displayed and on the right is how it changes after rotation. This is working fine in ios15 I know Apple having been making changes in this area, but the app is set to ios15 as the minimum deployment and I'm not using any of the new features, so I wasn't expecting this issue. Changing the navigation bar frame seems to have no effect Anybody any clues?
Posted
by rowets2.
Last updated
.
Post marked as solved
1 Replies
128 Views
I understand that shouldAutorotate has been deprecated in IOS16 and forcing orientations using UIDevice have also gone away. But it's not clear to me how we can prevent orientation changes using the new api. I have managed to force orientation changes using requestGeometryUpdate but nothing I do seems to stop it from rotating back again after the forced rotation. I've tried calling setNeedsUpdateOfSupportedInterfaceOrientations on both the current view controller and the navigation controller but supportedInterfaceOrientations never seems to be called. supportedInterfaceOrientations is called on the first load, but it seems to be ignored as regardless of what I put in there the device will rotate to all the options allowed in the info.plist. What trick am I missing?
Posted Last updated
.
Post not yet marked as solved
1 Replies
147 Views
UITextview's Spellchecker seem not to detect spells and show red dots at odd position in MacCatalyst: It does work well in iPhone and iPad though. I've activated the Spellcheck through storyboard, also tested with both Normal and Attributed strings. Even tried disabling the scrolling. But nothing seems to help! Does any one know about this behaviour?
Posted Last updated
.
Post not yet marked as solved
1 Replies
78 Views
hi, I have a small UIView box inside a larger box that's constrained to the superview(view). when I try to change the leading edges of the smaller box (referencing the trailing constrained to the larger box) it will disappear or fly off the screen, upon further investigation, I find that the constrain being changed is the top constrain of the smaller box... it's quite peculiar, the larger box uses essentially the same code and works as expected. The only difference I can think of is the larger box references to the edge "view" which Is fixed but not sure if that's what's causing the problem. here is the code. @IBAction func PinchOutlet(_ sender: UIPinchGestureRecognizer) {                 let newalphaLeadingConstrain = alphaLeadingConstrain.constraintWithMultiplier(alphaLeadingMultiplier)         self.alphaLeadingConstrain = newalphaLeadingConstrain         view.removeConstraint(self.alphaLeadingConstrain)         view.addConstraint(newalphaLeadingConstrain)         if sender.scale>1{             self.alphaLeadingMultiplier = 0.1         }         else{             self.alphaLeadingMultiplier = 0.5         }         self.view.layoutIfNeeded()     }
Posted Last updated
.
Post not yet marked as solved
1 Replies
2.2k Views
I have a register user screen for an app that uses a UITableView to create a list of required fields. Each section has the thing (i.e. "Username", "Email", etc) in the header, a text field, and a footer to display messages pertaining to that field, such as "Username too short." I have found two different ways of updating this text on the fly. The first way is to create an action for whenever the user types into those text fields and in that I call the following code: UIView.setAnimationsEnabled(false) self.tableView.beginUpdates() if let containerView = tableView.footerView(forSection: section) { containerView.textLabel!.textColor = UIColor.red containerView.textLabel!.text = "Username too short" containerView.textLabel!.font = UIFont(name: containerView.textLabel!.font.fontName, size: 12) containerView.sizeToFit() } self.tableView.endUpdates() UIView.setAnimationsEnabled(true)This works, updating the footer when I type into the text box (I update the text and message depending on what is needed). However, when I scroll down and for example the username section unloads, when I scroll back up the "Username too short" text is gone. When I again type into the text field it reappears. I have also had issues with this updating it when the section isn't rendered (as expected). Thus, I tried overriding the tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -&gt; UIView? method in the following way: override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -&gt; UIView? { let view = UIView(frame: CGRect(x: 8, y: 0, width: 100, height: 40)) let label = UILabel(frame: view.frame) label.text = "Username too short" label.sizeToFit() view.addSubview(label) view.frame = CGRect(x: 8, y: 0, width: 100, height: 20) return view }Again updating the text appropriately and not calling the previous code. This meant that I had to call tableView.reloadData() every time the user typed in a character. This also worked, but it caused the app to stop letting the user type in to the text field. They would have to click on it again to start typing after every character. I have tried countless ways of merging the two methods, attempting to call the former code in the tableView, but I found that whenever I returned a custom view tableView.footerView(forSection: &lt;anything&gt;) would return nil and if I called the tableViewmethod itself, I would have infinite recursion. I also tried many methods to try to get just the footer to reload (thus not losing the text view focus), but none of them seemed to work. How can I get the footer to update, persist when I unload the section (and as an extension be able to update it while the section isn't loaded), and not lose focus on the text field?I apologize in advance as I am a bit new to app development. For some context, I have a static table and I am referring to the headers and footers of each section, not the table footer.
Posted Last updated
.
Post not yet marked as solved
1 Replies
128 Views
Usually, when I display a UITableView (UITableViewStyleGrouped) somewhere, there's a nice strip of gray padding at the top, above the first cell in the first section. But, when displayed in a popover on an iPad, the same UITableView appears with the first cell aligned to the top edge, i.e., you can't see any gray padding. If you drag the UITableView down with your finger, you can see that the padding exists, but as soon as you let go, the UITableView snaps back so that the top cell is aligned with the top edge. Curiously, if the top section has a header string, the UITableView behaves as you would expect. Any thoughts are appreciated!
Posted
by motrek.
Last updated
.
Post not yet marked as solved
0 Replies
54 Views
I have a UICollectionView with a diffable data source and a global list header in a compositional layout (i.e., one header for the whole layout, not one per section). let layout = UICollectionViewCompositionalLayout() { ... } let listHeader = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(1)), elementType: ListHeader.self, alignment: .top ) layout.boundarySupplementaryItems = [listHeader] Sometimes, the list header changes its size, and I'd love to animate that. However, I cannot call reconfigureItems with diffable data source. If the new snapshot is identical to the old snapshot, the header size doesn't update in the list (even if I call layoutIfNeeded on the header view directly). If there are changes between the snapshots, the header size updates abruptly, without animation. How can I update and animate the size change of the global list header, regardless of whether the snapshot has changed or not?
Posted Last updated
.
Post not yet marked as solved
0 Replies
70 Views
Hello, I'm experiencing an issue with UITableViewDragDelegate and UITableViewDropDelegate where a random cell within the UITableView will disappear when dragging a cell around. I believe I'm either missing a step with these protocols, or this is a bug within UIKit. Any help would be greatly appreciated! I'm on Xcode 13.4 using an iOS 15.5 simulator. I've spun up some sample code that can easily reproduce one variant of the issue. This repro involves the "autoscroll" feature provided by these protocols, where the table will automatically scroll when a dragged cell approaches the top or bottom edge of the table. It also seems to happen more frequently when tableView(_:dropSessionDidUpdate:withDestinationIndexPath:) sometimes returns a UITableViewDropProposal with the move operation (for moves that are permitted) and other times returns a UITableViewDropProposal with the forbidden operation. This isn't the only time I've seen a cell disappearing with these drag & drop protocols, but it's the easiest to reproduce. When this bug does occur, you can use Xcode’s Debug View Hierarchy tool to inspect the cell that disappeared. Each time this happens, the cell is still within the view hierarchy, but its alpha has been set to 0. I have a ticket within Feedback Assistant (FB10449257) but I'm also posting here in case someone else has run into this issue. To reproduce the issue: Start by dragging a cell to the bottom of the table. Once the table scrolls to the bottom, drag the cell to the very bottom edge of the table's frame. This will cause the forbidden operation to be returned from tableView(_:dropSessionDidUpdate:withDestinationIndexPath:) because destinationIndexPath is nil. Drag the cell to the top edge of the table to scroll back up. A cell will be missing. Here's my sample code: import UIKit class ViewController: UIViewController {          lazy var tableView: UITableView = {         let table = UITableView(frame: view.bounds)         table.autoresizingMask = [.flexibleWidth, .flexibleHeight]         view.addSubview(table)         table.register(UITableViewCell.self, forCellReuseIdentifier: "DefaultCell")         return table     }()          lazy var dataSource: UITableViewDiffableDataSource<Int, Int> = {         .init(tableView: tableView) { tableView, indexPath, itemIdentifier in             let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultCell", for: indexPath)             var configuration = cell.defaultContentConfiguration()             configuration.text = "Item number \(itemIdentifier)"             cell.contentConfiguration = configuration             return cell         }     }()          override func viewDidLoad() {         super.viewDidLoad()         tableView.dataSource = dataSource         tableView.dragDelegate = self         tableView.dropDelegate = self                  var snapshot = dataSource.snapshot()         snapshot.appendSections([0])         snapshot.appendItems(Array(0...25))         dataSource.apply(snapshot, animatingDifferences: false)     } } extension ViewController: UITableViewDragDelegate {          func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {         let dragItem = UIDragItem(itemProvider: .init())         dragItem.localObject = dataSource.itemIdentifier(for:indexPath)!         return [dragItem]     }          func tableView(_ tableView: UITableView, dragSessionIsRestrictedToDraggingApplication session: UIDragSession) -> Bool {         true     } } extension ViewController: UITableViewDropDelegate {          func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {         guard destinationIndexPath != nil else {             print("destinationIndexPath is nil")             return UITableViewDropProposal(operation: .forbidden)         }         return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)     }          func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {         // This logic is missing safety checks and is just for demo purposes.         var snapshot = dataSource.snapshot()         let destination = coordinator.destinationIndexPath!         let dragItem = coordinator.items.first!.dragItem         snapshot.moveItem(dragItem.localObject as! Int, afterItem: dataSource.itemIdentifier(for: destination)!)         dataSource.apply(snapshot)         coordinator.drop(dragItem, toRowAt: destination)     } } Thank you!
Posted
by newman719.
Last updated
.
Post not yet marked as solved
1 Replies
110 Views
I can't get my latest iPhone app to run in portrait mode only. In Xcode I've checked only the box that says "Portrait" under Device Orientation, and I've also examined the Info.plist file to ensure that there aren't any hidden settings for other orientations. I've also tried checking or un-checking iPad, and checking "Requires Full Screen" when that option appears. No matter what I do, when I run the app on my phone and rotate the screen, the interface rotates. What am I doing wrong?
Posted
by flarosa.
Last updated
.
Post not yet marked as solved
0 Replies
56 Views
I am trying to set and maintain the zoomScale value on the scrollView associated with a WKWebView. I can set the value without issue. I have noticed, however, that when the size of the webpage changes (due to a change in content), the zoomScale gets reset back to 1. Also, this reset behavior does not occur if the zoomScale is set via a pinch gesture by the user. Is there something I can do to maintain the programmatically set zoomScale when the size of the web page changes?
Posted Last updated
.
Post marked as solved
1 Replies
81 Views
I am trying to add a UITableView element to a XIB which I want to present as a sheet from the bottom but I only get the option of static cells. Isn't it possible to have dynamic tables within a XIB or am I missing something?
Posted
by crsvld.
Last updated
.
Post not yet marked as solved
0 Replies
104 Views
When I hover the mouse over the NSTextAttachment image inside the UITextview, it should show this option to MarkUp. All native app including Notes, TextEditor, Mail have this behaviour: I think, by default, NSTextView will show the NSSharingServicePicker button when you hover over an image inside the text view. That’s true even for custom image-based NSTextAttachments in the attributed string. But it is not showing the button for UITextview in MacCatalyst. Also NSSharingService class is limited to MacOS only. Are there any alternative way to achieve this in MacCatalyst?
Posted Last updated
.
Post not yet marked as solved
2 Replies
2.1k Views
Has anyone else run into an error where a custom URI such as "myapp://test" will open the app with a urlscheme "myapp" but won't pick up the "test" portion of the URI? The code I am using below is in the AppDelegate.swift file:func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -&gt; Bool { @Binding var _: String = url.absoluteString print(url.absoluteString) Controller.message = url.absoluteString return true }The Controller is a struct with a static var "message" that I am using in a View. Nothing is printed out when I pass "myapp://test", but the app opens even if it is close.This does work, however, if I place this code in the SceneDelegate:func scene(_ scene: UIScene, openURLContexts URLContexts: Set&lt;UIOpenURLContext&gt;) { if let url = URLContexts.first?.url{ @Binding var _: String = url.absoluteString print(url.absoluteString) Controller.message = url.absoluteString print(Controller.message) } }This will print the correct URI, but if I try to use this URI when the app is closed out it will open, but no information will be passed.Is this a Swift 5.1 problem? Every tutorial/video I have found online uses the first code snippet in the AppDelegate file and I have triple checked to make sure it is the same. Everything is the same from the tutorials, but I'm still not getting any results.Thanks.Matt
Posted
by micma418.
Last updated
.