Discuss the different user interface frameworks available for your app.

All subtopics

Post

Replies

Boosts

Views

Activity

iOS 18 Beta UIPrintInteractionController present issue
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?
2
0
814
Aug ’24
SwiftUI NavigationSplitView - Nested List Not Animating
Hi All! I've encountered a SwiftUI NavigationSplitView bug in my app that I'd appreciate help with, I've spent quite some time trying to work out a solution to this problem. I have a main list, which has either a Location or LocationGroup. When selecting a Location, the detail view is presented. When selecting a LocationGroup, a subsequent list of Locations are presented (from the group). When tapping on any of these Locations, the NavigationStack does not animate (push the view), and when tapping back from it, it jumps to the main selection. The overall goal is to be able to present within the detail: of a NavigationSplitView a NavigationStack, and to be able to push onto that stack from both the main NavigationSplitView's list, and from the detail. I created the following sample code that reproduces the issue: ContentView.swift public enum LocationSplitViewNavigationItem: Identifiable, Hashable { case location(Location) case locationGroup(LocationGroup) public var id: UUID? { switch self { case .location(let location): return location.id case .locationGroup(let locationGroup): return locationGroup.id } } } struct ContentView: View { @State private var columnVisibility = NavigationSplitViewVisibility.doubleColumn @State private var selectedNavigationItem: LocationSplitViewNavigationItem? var body: some View { NavigationSplitView(columnVisibility: $columnVisibility) { LocationListView(selectedItem: $selectedNavigationItem, locationData: LocationSampleData(locations: LocationSampleData.sampleLocations, locationGroups: LocationSampleData.sampleLocationGroups)) } detail: { if let selectedLocation = selectedNavigationItem { switch selectedLocation { case .location(let location): LocationDetailView(selectedLocation: location) case .locationGroup(let locationGroup): LocationListView(selectedItem: $selectedNavigationItem, locationData: LocationSampleData(locations: locationGroup.locations)) } } } .navigationSplitViewStyle(.balanced) } } LocationListView.swift struct LocationListView: View { @Binding public var selectedItem: LocationSplitViewNavigationItem? var locationData: LocationSampleData var body: some View { List(selection: $selectedItem) { if let locations = locationData.locations { ForEach(locations) { location in NavigationLink(value: LocationSplitViewNavigationItem.location(location)) { Text(location.name) .bold() } } } if let locationGroups = locationData.locationGroups { ForEach(locationGroups) { locationGroup in NavigationLink(value: LocationSplitViewNavigationItem.locationGroup(locationGroup)) { Text(locationGroup.name) .bold() .foregroundStyle(.red) } } } } .navigationTitle("Saturday Spots") .navigationBarTitleDisplayMode(.large) } } LocationDetailView.swift struct LocationDetailView: View { var selectedLocation: Location var body: some View { Text(selectedLocation.name) .font(.largeTitle) .bold() .foregroundStyle(LinearGradient( colors: [.teal, .indigo], startPoint: .top, endPoint: .bottom )) .toolbarBackground( Color.orange, for: .navigationBar ) .toolbarBackground(.visible, for: .navigationBar) } } Location.swift import CoreLocation struct LocationSampleData { var locations: [Location]? var locationGroups: [LocationGroup]? static let sampleLocations: [Location]? = Location.sample static let sampleLocationGroups: [LocationGroup]? = [LocationGroup.sample] } public struct Location: Hashable, Identifiable { var name: String var coordinates: CLLocationCoordinate2D var photo: String public var id = UUID() static public let sample: [Location] = [ Location(name: "Best Bagel & Coffee", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf"), Location(name: "Absolute Bagels", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf"), Location(name: "Tompkins Square Bagels", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf"), Location(name: "Zabar's", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf"), ] static public let oneSample = Location(name: "Absolute Bagels", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf") } public struct LocationGroup: Identifiable, Hashable { var name: String var locations: [Location] public var id = UUID() static public let sample: LocationGroup = LocationGroup(name: "Bowling", locations: [ Location(name: "Frames Bowling Lounge", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf"), Location(name: "Bowlero Chelsea Piers", coordinates: CLLocationCoordinate2D(latitude: 123, longitude: 121), photo: "asdf") ]) } extension CLLocationCoordinate2D: Hashable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude } public func hash(into hasher: inout Hasher) { hasher.combine(latitude) hasher.combine(longitude) } }
2
0
1k
Aug ’24
UlTextView erroneously overrides string attributes when applying spellchecker annotation attributes (regression)
UITextView erroneously overrides string attributes when applying spellchecker annotation attributes. It doesn't need any particular setting. Default UITextView instance with attributed text let textView = UITextView(usingTextLayoutManager: true) textView.spellCheckingType = .yes Once spellcheck attributes get applied, other attributes like foreground color get applied to the misspelled words. This behavior happens only on Mac Catalyst, and started to appear on macOS 14 or newer. Please check the Xcode project that demonstrates the issue https://github.com/user-attachments/files/16689336/TextEditor-FB14165227.zip Open TextEditor project Select "My Mac (Mac Catalyst)" build destination Run the project. A window with a text area should appear Select the whole text (either using mouse or keyboard command+a) Observe how foregroundColor changes to text (this is the issue) That eventually led to crash 💥 This bug is reported to Apple FB14165227
1
0
729
Aug ’24
"Add to Apple Wallet" (PKAddPassButton) title localization to device language
Hi there! My app supports one language by default Ukrainian (uk) and does not support multiple languages. In Xcode settings "Development Language" is set to Ukrainian by default also. I have a PKAddPassButton on a ViewController and "Add to Apple Wallet" always appears in Ukrainian (Tested on real device iOS 15/16/17). Apple's "Getting Started with Apple Pay: In-App Provisioning, Verification, Security, and Wallet Extensions” document states that "The Add to Apple Wallet button adapts to the device language and the light and dark appearances, but the issuer app needs to adapt the language of the row selector text." When I change device language to French the “Add to Apple Wallet” button does not change to French. I created a fresh swift app, added PKAddPassButton the "Add to Apple Wallet" button, General -> Language & Region changed the device language to French, etc, but the "Add to Apple Wallet" button is always in English. Has anyone run into the same issue? How to adapt the "Add to Apple Wallet" button to the device system language?
2
0
1.1k
Aug ’24
Attempting to add scrubbing to UISlider
I made a custom slider by subclassing UISlider, and I'm trying to add scrubbing functionality to it, but for some reason the scrubbing is barely even noticeable at 0.1? In my code, I tried multiplying change in x distance by the scrubbing value, but it doesn't seem to work. Also, when I manually set the scrubbing speed to a lower value such as 0.01, it does go slower but it looks really laggy and weird?? What am I doing wrong? Any help or advice would be greatly appreciated! Subclass of UISlider: class SizeSliderView: UISlider { private var previousLocation: CGPoint? private var currentLocation: CGPoint? private var translation: CGFloat = 0 private var scrubbingSpeed: CGFloat = 1 private var defaultDiameter: Float init(startValue: Float = 0, defaultDiameter: Float = 500) { self.defaultDiameter = defaultDiameter super.init(frame: .zero) value = clamp(value: startValue, min: minimumValue, max: maximumValue) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ rect: CGRect) { super.draw(rect) clear() createThumbImageView() addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged) } // Clear elements private func clear() { tintColor = .clear maximumTrackTintColor = .clear backgroundColor = .clear thumbTintColor = .clear } // Call when value is changed @objc private func valueChanged(_ sender: SizeSliderView) { CATransaction.begin() CATransaction.setDisableActions(true) CATransaction.commit() createThumbImageView() } // Create thumb image with thumb diameter dependent on thumb value private func createThumbImageView() { let thumbDiameter = CGFloat(defaultDiameter * value) let thumbImage = UIColor.red.circle(CGSize(width: thumbDiameter, height: thumbDiameter)) setThumbImage(thumbImage, for: .normal) setThumbImage(thumbImage, for: .highlighted) setThumbImage(thumbImage, for: .application) setThumbImage(thumbImage, for: .disabled) setThumbImage(thumbImage, for: .focused) setThumbImage(thumbImage, for: .reserved) setThumbImage(thumbImage, for: .selected) } // Return true so touches are tracked override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { let location = touch.location(in: self) // Ensure that start location is on thumb let thumbDiameter = CGFloat(defaultDiameter * value) if location.x < bounds.width / 2 - thumbDiameter / 2 || location.x > bounds.width / 2 + thumbDiameter / 2 || location.y < 0 || location.y > thumbDiameter { return false } previousLocation = location super.beginTracking(touch, with: event) return true } // Track based on moving slider override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { guard isTracking else { return false } guard let previousLocation = previousLocation else { return false } // Reference // location: location of touch relative to device // delta location: change in touch location WITH scrubbing // adjusted location: location of touch to slider bounds (WITH scrubbing) // translation: location of slider relative to device let location = touch.location(in: self) currentLocation = location scrubbingSpeed = getScrubbingSpeed(for: location.y - 50) let deltaLocation = (location.x - previousLocation.x) * scrubbingSpeed var adjustedLocation = deltaLocation + previousLocation.x - translation if adjustedLocation < 0 { translation += adjustedLocation adjustedLocation = deltaLocation + previousLocation.x - translation } else if adjustedLocation > bounds.width { translation += adjustedLocation - bounds.width adjustedLocation = deltaLocation + previousLocation.x - translation } self.previousLocation = CGPoint(x: deltaLocation + previousLocation.x, y: location.y) let newValue = Float(adjustedLocation / bounds.width) * (maximumValue - minimumValue) + minimumValue setValue(newValue, animated: false) sendActions(for: .valueChanged) return true } // Reset start and current location override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { self.currentLocation = nil self.translation = 0 super.touchesEnded(touches, with: event) } // Thumb location follows current location and resets in middle override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect { let thumbDiameter = CGFloat(defaultDiameter * value) let origin = CGPoint(x: (currentLocation?.x ?? bounds.width / 2) - thumbDiameter / 2, y: (currentLocation?.y ?? thumbDiameter / 2) - thumbDiameter / 2) return CGRect(origin: origin, size: CGSize(width: thumbDiameter, height: thumbDiameter)) } private func getScrubbingSpeed(for value: CGFloat) -> CGFloat { switch value { case 0: return 1 case 0...50: return 0.5 case 50...100: return 0.25 case 100...: return 0.1 default: return 1 } } private func clamp(value: Float, min: Float, max: Float) -> Float { if value < min { return min } else if value > max { return max } else { return value } } } UIView representative: struct SizeSlider: UIViewRepresentable { private var startValue: Float private var defaultDiameter: Float init(startValue: Float, defaultDiameter: Float) { self.startValue = startValue self.defaultDiameter = defaultDiameter } func makeUIView(context: Context) -> SizeSliderView { let view = SizeSliderView(startValue: startValue, defaultDiameter: defaultDiameter) view.minimumValue = 0.1 view.maximumValue = 1 return view } func updateUIView(_ uiView: SizeSliderView, context: Context) {} } Content view: struct ContentView: View { var body: some View { SizeSlider(startValue: 0.20, defaultDiameter: 100) .frame(width: 400) } }
7
0
677
Aug ’24
SwiftUI Navigation Issue: Handling Navigation Across Multiple Tabs with Separate Navigation Stacks
I'm working on a SwiftUI application that uses programmatic navigation with enums in a NavigationStack. My app is structured around a TabView with different tabs, each having its own navigation stack. I need to navigate to the same view from different tabs, but each tab has a separate navigation stack with custom paths. Here's a simplified version of my setup: class AppState: ObservableObject { @Published var selectedTab: Tab = .feeds @Published var tabANavigation: [TabANavDestination] = [] @Published var tabBNavigation: [TabBNavDestination] = [] } enum TabANavDestination: Hashable { case itemList() case itemDetails(String) } enum TabBNavDestination: Hashable { case storeList() case itemList() case itemDetails(String) } For example: TabA: ItemsListScreen -> DetailsScreen. TabB: StoreList -> ItemsListScreen -> DetailsScreen I want to navigate from ItemsListScreen to DetailsScreen, but I can't use the same method to append the navigation state in both tabs: appState.tabANavigation.append(.itemDetails(id)) How can I manage navigation across these different tabs, ensuring that the same screen (e.g., DetailsScreen) is accessible from different paths and tabs with their own navigation stacks? What’s the best approach to handle this scenario in a complex navigation setup?
2
0
816
Aug ’24
Xcode not recognizing GoogleMaps theme colors with Swift
I have an Xcode project written in Objc where Xcode recognizes GoogleMaps code (GMS SDK 9) and applies appropriate theme colors. I'm porting the app into Swift and Xcode does not seem recognize GMS code for theme colors. The theme otherwise works and the Swift/GMS code works (ie the app works). I've tried 'Clean All Targets', deleting the DerivedData folder, cleaning the Xcode cache, re-installing the GMS SDK (both CocoaPod & manual methods) etc. When the Swift project is re-opened, Xcode shows the project is being re-indexed. After indexing, the rest of the code is 'colorized' - but not the GMS code. Both StackOverflow & StackExchange rejected this question. And Apple Developer Support has not been able to help (Case ID: 102334926141). Any advice will be greatly appreciated. TIA
6
0
733
Jul ’24
UI Tab Bar
Anyone else get these warnings when using UI Tab Bar in visionOS? Are these detrimental to pushing my visionOS app to the App Review Team? import SwiftUI import UIKit struct HomeScreenWrapper: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UITabBarController { let tabBarController = UITabBarController() // Home View Controller let homeVC = UIHostingController(rootView: HomeScreen()) homeVC.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0) // Brands View Controller let brandsVC = UIHostingController(rootView: BrandSelection()) brandsVC.tabBarItem = UITabBarItem(title: "Brands", image: UIImage(systemName: "bag"), tag: 1) tabBarController.viewControllers = [homeVC, brandsVC] return tabBarController } func updateUIViewController(_ uiViewController: UITabBarController, context: Context) { // Update the UI if needed } } struct HomeScreenWrapper_Previews: PreviewProvider { static var previews: some View { HomeScreenWrapper() } }
1
0
597
Jun ’24
UI Binding Issue with Consecutive Modal Prompts on Latest iOS Versions
Hi team, Currently, I am using two Modal prompts consecutively to display force update popups based on a condition. However, there's an issue where the UI thread is occasionally not binding properly after dismissing the first prompt. Please ensure that after dismissing the first prompt, the second prompt is not bound. After reviewing everything, I understand this is an iOS core library binding issue and it's occurring from the latest iOS version onwards. Could you please provide me with a solution to resolve this issue? Thank you!
0
1
605
Jun ’24
NavigationBar Back Button Color
I am trying to change the colour of the "Back" from blue to white but having difficulty do so, if anyone can suggest me a better way to do it would be grateful. "import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = UIColor(red: 0.216, green: 0.776, blue: 0.349, alpha: 1) appearance.titleTextAttributes = [.foregroundColor: UIColor.white] appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white] UINavigationBar.appearance().standardAppearance = appearance UINavigationBar.appearance().scrollEdgeAppearance = appearance UINavigationBar.appearance().tintColor = .white return true } }"
1
1
1k
Jun ’24
Delete button in default NSSavePanel for new document
I just noticed that when closing a new document with edits in MacOS Sonoma that it skips the Save/Don't Save/Cancel panel and goes directly to default NSSavePanel with Delete/Cancel/Save buttons. The problem is that when I click "Delete" nothing happens. It should have simple solution, but I could not find anything. How does one respond to the "Delete" button? My undocumented (as far as I can tell) hack was to implement document:didSave:contextinfo selector for runModalSavePanelForSaveOperation. It appears that in this method for a new document: Delete button has didSave=YES (even though it did not save) and the document fileURL nil Cancel button has didSave=NO and document fileURL nil Save button has didSave=YES and document filieURL to saved file I can handle Delete button this way, but since it is not a documented method, it make me uncomfortable. For example what happens is user clicks "Save", but the save has an error? As an aside, since Apple is now working with ChatGPT, I thought it might provide some help. I asked it how I can respond to "Delete" button in MacOS Sonoma and it said to implement deleteDocument: in your NSDocument subclass. I pointed out to ChatGPT that deleteDocument: does not exist. It said "you are correct" and you should instead check the returned result from runModalSavePanelForSaveOperation and look for "stop" action. I pointed out to ChatGPT that runModalSavePanelForSaveOperation is void and does not return a result, it said again, "you are correct." It gave a third option which basically said to override runModalSavePanelForSaveOperation and build your own save panel from scratch. I didn't know if I should trust this answer. I reverted to my hack and wrote this post. Also ChatGPT never apologized for wasting my time with the wrong answers.
3
0
854
Jun ’24
UIView can't handle external keyboard shortcuts combined with Command key (UIKeyCommand)
Keyboard shortcuts that use the Command key modifier are not handled properly, and the UIKeyCommand action and pressesBegan and pressesEnded methods are not called at all or are called unreliably. It is easy to reproduce using this snippet: class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let textView = MyTextView() textView.font = UIFont.systemFont(ofSize: 24) textView.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec efficitur eros vitae dui consectetur molestie. Integer sed massa rutrum, pharetra orci eget, molestie sem. Fusce vestibulum massa nisi, vitae viverra purus condimentum et. Sed nec turpis aliquam, tempus enim sit amet, gravida libero. Praesent scelerisque venenatis nunc, vel convallis nisl auctor vitae. Mauris malesuada tempus pharetra. Nullam ornare venenatis ullamcorper. In viverra feugiat tincidunt. Nullam iaculis urna eu semper rutrum. " textView.isEditable = true textView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(textView) NSLayoutConstraint.activate([ textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), textView.bottomAnchor.constraint(equalTo: view.bottomAnchor), textView.leadingAnchor.constraint(equalTo: view.leadingAnchor), textView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) } } class MyTextView: UITextView { override var keyCommands: [UIKeyCommand]? { [ UIKeyCommand(input: "[", modifierFlags: .command, action: #selector(commandAction(_:))) ] } override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) { print("pressesBegan") super.pressesBegan(presses, with: event) } override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) { print("pressesEnded") super.pressesEnded(presses, with: event) } @objc private func commandAction(_ sender: Any?) { print("commandAction") } } Run the code in a Simulator or on a Device with an external keyboard connected. Observe the console for a string "commandAction" when pressing the combination Command + [ on the keyboard. Result it not predictable, the UIKeyCommand is not called at all, or called in a loop, or sometimes called after change selection in the UITextView. The same with pressesBegan and pressesEnded. Compare results with the change where instead of Command modifier, we use Control modifier eg.: "UIKeyCommand(input: "[", modifierFlags: .command, action: #selector(commandAction(_:))" - now each keyboard shortcut is properly reported to methods. The UIKeyCommand.wantsPriorityOverSystemBehavior property changes nothing. Behavior reproducible in the Simulator and on the Device (iPad) (the issue was confirmed during online WWDC24 Labs) Reported as FB13897415
0
0
677
Jun ’24
How to replicate UIImageView's `scaleAspectFill` for Images inside a custom Layout?
I've defined a custom layout container by having a struct conform to Layout and implementing the appropriate methods, and it works as expected. The problem comes when trying to display Image, as they are shown squished when just using the .resizable() view modifier, not filling the container when using .scaledToFit() or extending outside of the expected bounds when using .scaledToFill(). I understand that this is the intended behaviour of these modifiers, but I would like to replicate UIImageView's scaledAspectFill. I know that this can usually be achieved by doing: Image("adriana-wide") .resizable() .scaledToFill() .frame(width: 200, height: 200) .clipped() But hardcoding the frame like that defeats the purpose of using the Layout, plus I wouldn't have direct access to the correct sizes, either. The only way I've managed to make it work is by having a GeometryReader per image, so that the expected frame size is known and can bet set, but this is cumbersome and not really reusable. GalleryGridLayout() { GeometryReader { geometry in Image("adriana-wide") .resizable() .scaledToFill() .frame(width: geometry.size.width, height: geometry.size.height) .clipped() } [...] } Is there a more elegant, and presumably efficient as well as reusable, way of achieving the desired behaviour? Here's the code of the Layout.
4
0
943
Jun ’24
Can't Select UITextField in UITableView
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.
2
0
932
May ’24
initWithURL vs initWithBundleIdentifier giving different permissions
I am directed from https://discuss.appium.io/t/create-multiple-instances-of-the-same-app/41266/14?u=lxnm, the context is that Appium max2 driver is implementing the activating of MacOS app using XCTest API methods. There are 2 ways to implement the activating of the app, using app path (calling initWithURL) and bundle id (calling initWithBundleIdentifier). This pull request shows how the XCTest methods are called when using the Mac2 driver, specifically in the file WebDriverAgentMac/WebDriverAgentLib/Routing/FBSession.m. The problem is that I am able to launch my MacOS app(it is a company app) using bundle id, but when I launch the app with app path, I receive XcodeBuild errors: [WebDriverAgentMac] [xcodebuild] XCTExpectFailure: matcher accepted Assertion Failure: Failed to launch com.company.companyApp: You do not have permission to run the application “companyApp”. You don’t have permission. To view or change permissions, select the item in the Finder and choose File > Get Info. (Underlying Error: The operation couldn’t be completed. Operation not permitted) I followed this to enable R+W permissions to all users, but the same error is displayed.
3
0
1.1k
Jan ’24