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

UIKit Documentation

Post

Replies

Boosts

Views

Activity

Getting build error in tvOS for UITableView
I want to use uitableview in tvos to show list of string data but compiler is throughing following errors in generated header: "No type or protocol named 'UITableViewDataSource'" And "Attempting to use the forward class 'UITableView' as superclass of 'TWOSSelectionTableTVOS'" Even though this code is working is ios . My code structure is as follow : SelectionTable.swift: import UIKit class TWOSSelectionTableTVOS : UITableView { private var vDataSrc:[String]! func SetDataSrc (_ pDataSrc:[String]) { self.vDataSrc = pDataSrc } func UpdateDataSrc (_ pStringList:[String]) { self.vDataSrc += pStringList } func GetDataSrc () -> [String] { return self.vDataSrc } } PaintUI.swift : import UIKit @objc class PaintUI: NSObject,UITableViewDelegate, UITableViewDataSource { static let uShared = PaintUI () @objc static func updateUIMessage() { DispatchQueue.main.async { ExecuteInlineSelectionTable () } } func tableView (_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell (withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "hello" return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let viewcontroller: TWIOSViewController! viewcontroller = StaticContext.sViewController } public static func ExecuteInlineSelectionTable () { let selectiontable:TWOSSelectionTableTVOS! selectiontable = TWOSSelectionTableTVOS () selectiontable.register (UITableViewCell.self, forCellReuseIdentifier: "cell") selectiontable.dataSource = uShared selectiontable.delegate = uShared selectiontable.isScrollEnabled = true // TODO : will add selection table in view heriearchy but currently getting // compilation error } } And finally calling PaintUI.updateUIMessage () , it is throughing above errors for tvOS only but in case of ios code is working fine.
0
0
615
Jan ’24
event handler for button click not getting triggered
when i am adding new view to replace viewcontroller's view like this : let viewcontroller: UIViewController! let rootview:UIView! viewcontroller = UIViewController () rootview = UIView (frame:viewcontroller.view.bounds) viewcontroller.view = rootview // Adding a button let button = UIButton(type: .system) button.setTitle("Tap Me", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 18) button.addTarget(self, action: #selector(buttonTapped), for:.allEvents) viewcontroller.view.addSubview(button) For ios(iPhone/ipad) , i am able to get button click event . But in case of tvOS , i am not getting button click event. But in case of tvOS if use the default view of viewcontroller like this , i am getting button click events and things works fine: let viewcontroller: UIViewController! viewcontroller = UIViewController () // Adding a button let button = UIButton(type: .system) button.setTitle("Tap Me", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 18) button.addTarget(self, action: #selector(buttonTapped), for:.allEvents) viewcontroller.view.addSubview(button) Is this some bug for tvOS or for tvOS this suppose to happen this way ?
0
0
686
Jan ’24
React Native - iOS - open iMessages Share Extension
I am creating an app where i am opening the direct share extension in app for different apps like instagram, snapchat and whatsapp. It is working fine i know there share extension bundle id and it open perfectly. I also need to open the iMessages share extension in app i have found the bundle id of iMessage share extension it is com.apple.UIKit.activity.Message but when i try to open it got error extension not found. Any one have any idea how i can find the right bundle if for iMessage share extension ? I am using an iOS SPM package LNExtensionExecutor and create a bridge between React Native and this native package.
0
0
778
Jan ’24
Changing screen orientation without rotation and view resizing animations
I need to instantly and without rotation animation change the screen orientation (and accordingly the size of the frame self.view in the UIViewController). If I do it like this in UIViewController: - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [CATransaction begin]; [CATransaction setDisableActions:YES]; [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { [self.view setFrame:CGRectMake(0, 0, size.width, size.height)]; } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { [CATransaction commit]; }]; } Then, at the moment the screen orientation changes to, I see a flickering of view. How can I do what is necessary?
0
0
506
Jan ’24
Access file from File app works inside my application, but doesn't work if I launch my app from the File app
Hi! I've got an application that can handle json (export/import). To achieve that I created a new Document Type in the info.plist, filed the imported and exported Type Identifiers, and created a new UTType. At first I was trying on the simulator and everything worked fine. I was able to created files and store them in the File app, and then read them back. I also implemented the func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) to handle documents opened from outside the application. Now when I moved on onto a real device, I noticed that I had to test the access with guard url.startAccessingSecurityScopedResource() else { throw ImportError.accessDenied } defer { url.stopAccessingSecurityScopedResource() } but I get a weird behavior : when opening a file from File app with my app launched, everything works fine. But if I try to launch my application (previously killed) from a file in the File app, startAccessingSecurityScopedResource always returns false I tried to add the NSFileCoordinator().coordinate(readingItemAt: url, error: &error) { (url) in but I get the same behavior. I guess my files and UTType are correctly declared as I only see them from inside the `UIDocumentPickerViewController`` and from the File app, I see my application in the share sheet What am I missing here ? Thanks
1
0
1.4k
Jan ’24
[Solved] Swift not entering while loop while condition is true
Hello! When opened viewController is closed, and the caller viewController appears, I iterate through the data that the called viewController modified. And here's the strange part - I can't iterate through the classes in the array, for some reason, even though the conditions for while = true are met - Swift runtime refuses to enter inside while loop. I've tryed to emulate this situation in playground - there it works just fine. Is it bug in Swift, or some multighreading stuff ? Please help ? Code is: https://github.com/afirthes/Numberator UPDATE: It was some xcode debug caching error, after restart it worked fine.
0
0
281
Jan ’24
Reality Kit iOS 17 Update
I have a project that I started on iOS 16 and when iOS 17 came out I was excited about implementing the object capture feature using the reality kit. However, when I check the sample project, the reality kit in it has the object session, object capture view, and object pointcloud classes ready to use, but when I search up these classes and their respective functions on my project, they don't exist. I updated the deployment target to iOS 17.3, yet I still can't use the functions. How do I fix this?
0
0
342
Jan ’24
Custom UIContentConfiguration for TableView Separator Insets
Hi, I have created a custom UIContentConfiguration + UIContentView for a TableView and using the custom Configuration and the default Configuration from UIListContentConfiguration in a same TableView (Style insetGrouped). But the separators from the custom configuration are different than that from the default configuration. And I didn't see an option to modify this through the custom configuration. Do anybody know how this is done with UIListContentConfiguration? For me currently the only option seems to be using "cell.separatorInset", but for the UIListContentConfiguration I don't need this. In the image below you see the problem. First, third and fifth cell is default configuration (UIListContentConfiguration.valueCell()). Second and fourth is the custom configuration. And under the custom configuration cells the separator is beginning at zero. This can be fixed with: cell.separatorInset.left = 20. This one is an example without image, but if I add an image for the default configuration, the text is much more behind and the fix with cell.separatorInset.left = 20 is not working in this case. For default configuration: let cell = tableView.dequeueReusableCell(withIdentifier: "default", for: indexPath) var config = UIListContentConfiguration.valueCell() config.text = "Test" config.secondaryText = "Test" cell.contentConfiguration = config return cell For custom configuration: Configuration + ContentView: struct SwitchConfiguration: UIContentConfiguration { var text: String? var value: Bool var delegate: SwitchDelegate? func makeContentView() -> UIView & UIContentView { return SwitchContentView(configuration: self) } func updated(for state: UIConfigurationState) -> SwitchConfiguration { return self } } class SwitchContentView: UIView, UIContentView { var configuration: UIContentConfiguration { didSet { self.configure() } } private let textLabel: UILabel = UILabel() private let `switch`: UISwitch = UISwitch() init(configuration: UIContentConfiguration) { self.configuration = configuration super.init(frame: .zero) self.switch.addTarget(self, action: #selector(self.switchValueDidChange(_:)), for: .valueChanged) self.addSubview(self.textLabel) self.addSubview(self.switch) self.directionalLayoutMargins = .init(top: 8, leading: 20, bottom: 8, trailing: 8) self.textLabel.translatesAutoresizingMaskIntoConstraints = false self.textLabel.leadingAnchor.constraint(equalTo: self.layoutMarginsGuide.leadingAnchor).isActive = true self.textLabel.centerYAnchor.constraint(equalTo: self.layoutMarginsGuide.centerYAnchor).isActive = true self.switch.translatesAutoresizingMaskIntoConstraints = false self.switch.trailingAnchor.constraint(equalTo: self.layoutMarginsGuide.trailingAnchor, constant: -16).isActive = true self.switch.centerYAnchor.constraint(equalTo: self.layoutMarginsGuide.centerYAnchor).isActive = true self.switch.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor).isActive = true self.switch.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor).isActive = true self.configure() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func configure() { guard let config = self.configuration as? SwitchConfiguration else { return } self.textLabel.text = config.text self.switch.isOn = config.value } @IBAction func switchValueDidChange(_ switch: UISwitch) { guard let config = self.configuration as? SwitchConfiguration else { return } config.delegate?.switchValueDidChange(`switch`.isOn) } } Cell: let cell = tableView.dequeueReusableCell(withIdentifier: "custom", for: indexPath) var config = SwitchConfiguration() config.text = "Test" config.value = true cell.contentConfiguration = config //cell.separatorInset.left = 20 return cell
0
1
568
Jan ’24
Scrolling sticker browser on a Messages App sheet causes sheet to move
As someone who learned Swift via SwiftUI, UIKit is completely alien to me, so I apologize if this is actually a very simple issue. I have a Messages extension that includes a sticker browser within it. In this extension, the MSMessagesAppViewController hosts a SwiftUI View, which in turn hosts a UIViewRepresentable version of MSStickerBrowserView. The whole Messages App sheet moves with an upward drag, and can switch to its expanded mode, whenever the browser is scrolled to the top (first sticker is at top left), but it doesn't budge when the browser is scrolled to the other end when it should allow the sheet to move upward with the drag. It seems something is reversed within the gesture priority management that allows a sheet to be moved in the appropriate direction when a contained scrollview is at the appropriate end. Things I've tried while reaching a diagnosis include: Limiting the presentation style to compact (the modal still moves, but never succeeds in changing) Adding competing highPriorityGestures in the SwiftUI view, set at various locations Inserting a rectangle with allowsHitTesting(false) beneath the browser Changing firstResponder statuses for all relevant views Changing GestureResponder priorities (there are no gesture responders in all views examined) Things I've considered but don't have the technical skills to implement: Have the view scroll a little downwards programmatically (like what can be done via ScrollViewReader in SwiftUI), but I have no idea how this can be done via MSStickerBrowserView or UIKit in general. Maybe the MSStickerBrowserView thinks its always in the expanded state (when the sheet is expanded, the end-drags work fine). If this is the case, if there's a way to either fix this misconception (via controller's didTransition) or do away with end drags in general, the problem should go away. Any pointers would be greatly appreciated!
2
0
818
Jan ’24
iOS 17 - Popover ModalPresentationStyle freeze UI
Hello Dev, Recently my client reported freezing the app screen when trying to dismiss it. Our application is related to music. When I checked the flow on the Simulator, I got the same case on the iPhone 15 series. I debugged the code and what I saw was CPU usage got 100% when I tried to pull down the model presented popover controller. I have checked the same flow multiple times and it worked 3-4 times and Additionally, it worked on some real devices and simulators too. So I can't understand what causing this issue. Can you please help me on this? I'm looking forward to hearing from you. Thank you in advance!
0
0
523
Jan ’24
UIHostingController question...
I have a SwiftUI view that works as expected in a full SwiftUI context. But I now need to use it in a UIViewController. It mostly works, but I'm trying to expose an @State var out to the viewController, and it only ever returns the initial value. Any guidance for how best to pass out this @State var? I could make it be a binding, but in my pure SwiftUI code, it works fine as @State (ie EditorView's container view does not need to know about sliderVal) thanks, in advance, for any suggestions import SwiftUI import UIKit class ViewController: UIViewController { var host: UIHostingController<EditorView>? override func viewDidLoad() { super.viewDidLoad() host = .init(rootView: EditorView()) guard let host = host else { return } addChild(host) host.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(host.view) host.didMove(toParent: self) } @IBAction func helloTapped(sender: UIButton) { guard let sliderValue = host?.rootView.sliderVal else { return } print("UIKit sliderValue: \(sliderValue)") } } struct EditorView: View { @State var sliderVal: Double init(sliderVal: Double? = nil) { _sliderVal = State(initialValue: sliderVal ?? 7) } var body: some View { VStack { Slider(value: $sliderVal, in: 1...10) Text("sliderVal: \(sliderVal)") } } } (NOTE: in order to see this code snippet in action you will need to create a button in the storyboard and link it to helloTapped)
2
0
790
Jan ’24
TipView can't show
import SwiftUI import TipKit struct ChatRoomView: View { @StateObject private var socketManager = SocketIOManager() @State private var inputText: String = "" @StateObject var viewModel = SignInWithAppleViewModel() @Binding var isCall: Bool @State private var isSheet = false @State private var ShowView = false var learnlisttip = KeyTip() @Binding var showShareSheet: Bool @Binding var codeshar: String var body: some View { NavigationStack{ VStack { if let roomCode = socketManager.roomCode { ZStack{ VStack{ HStack{ Text("Room Key: \(roomCode)") .font(.title) .onAppear{ codeshar = roomCode self.isCall = true } Button(action:{ self.showShareSheet = true }, label:{ Image(systemName: "square.and.arrow.up.fill") .accessibilityLabel("Share") }) } .padding(20) TipView(learnlisttip, arrowEdge: .top) .glassBackgroundEffect() .offset(z: 20) Spacer() } List(socketManager.messages, id: \.self) { message in Text(message) } TextField("input", text: $inputText) Button("send") { socketManager.sendMessage(roomCode: roomCode, message: inputText) inputText = "" } } .sheet(isPresented: $showShareSheet) { let shareContent = "Open SpatialCall, Join this Room, Key is: \(codeshar)" ActivityView(activityItems: [shareContent]) } } else { HStack{ Button(action:{ withAnimation{ socketManager.createRoom() } }, label: { VStack{ Image(systemName: "phone.circle.fill") .symbolRenderingMode(.multicolor) .symbolEffect(.appear, isActive: !ShowView) .font(.largeTitle) Text("Add Room") .font(.title3) } }) .buttonStyle(.borderless) .buttonBorderShape(.roundedRectangle) .padding(.horizontal, 30) .glassBackgroundEffect() .offset(z: 20) .scaleEffect(1.5) .padding(60) Button(action:{ withAnimation{ self.isSheet = true } }, label: { VStack{ Image(systemName: "phone.badge.checkmark") .symbolRenderingMode(.multicolor) .symbolEffect(.appear, isActive:!ShowView) .font(.largeTitle) Text("Join Room") .font(.title3) } }) .buttonStyle(.borderless) .buttonBorderShape(.roundedRectangle) .padding(.horizontal, 30) .glassBackgroundEffect() .offset(z: 20) .scaleEffect(1.5) .padding(70) } } } .onAppear { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { withAnimation { self.ShowView = true } } } .sheet(isPresented: $isSheet){ VStack{ Text("Join Room") .font(.largeTitle) Text("You need to get the key to the room.") TextField("Key", text: $inputText) .padding(30) .textFieldStyle(.roundedBorder) Button(action:{ socketManager.joinRoom(roomCode: inputText) self.isSheet = false }, label: { Text("Join Room") .font(.title3) }) .padding(50) } .padding() } .sheet(isPresented: $socketManager.showRoomNotFoundAlert) { Text("The room does not exist. Please check whether the Key you entered is correct.") .font(.title) .frame(width: 500) .padding() Button(action:{ self.socketManager.showRoomNotFoundAlert = false }, label: { Text("OK") .font(.title3) }) .padding() } } } } In the above code (this is a visionOS project), when I click Share, it can't display Sheet normally, and TipView can't be displayed either. Why?
1
0
751
Jan ’24
Detect foreground/background change
In ios17 and above, I can detect when swiftUI app goes into and out of background using: @Environment(\.scenePhase) private var phase ... .onChange(of: phase) { switch phase { case .background: print("entering background...") case .active: print("entering foreground...") default: break } } Is there a straightforward way to do this in SwiftUI for ios 16? I've found some examples using UIKit, but I am not that swift (sorry, couldn't resist) with that framework.
6
0
1.7k
Jan ’24
Swift Language Version and @MainActor
The app I work on has the Swift Language Version set to Swift 4.2 for the Compiler Language. There has been some issues with users experiencing crashes due to UI changes not occurring on the main thread. I've been unable to reproduce the crash and using the Main Thread Checker has turned up nothing. So to fix this I assumed I could make the functions that are doing the navigating @MainActor functions, but that seems to have fixed nothing. Xcode doesn't seem to have an issue with me including the @MainActor attribute on the functions, the build works and nothing seems amiss. But I'm wondering if because I'm compiling with Swift 4.2 (and I believe @MainActor was added in Swift 5.5), it's not actually using @MainActor attribute to ensure the code is run on the main thread?
1
0
385
Jan ’24
Crashing when going from Compact to Two Over Secondary in UISplitViewController on iPadOS 17
I have been struggling with a crash bug that begin popping up in iPadOS 17 when we moved our app over to building under Xcode 15. It is important to note that the prior release, built under Xcode 14 works fine. Also, the crash does not occur in versions of iPadOS prior to iPadOS 17, even when built under Xcode 15. The main view controller is a UISplitView that has primary, secondary, and supplemental views. Each, hosted in a UINavigationController. The primary view has the navigation bar hidden (this is important). If the supplemental view has an additional view controller pushed onto the navigation stack, hence a back button is being shown in the middle navigation controller, and the app is transitioned to a compact size class (secondary controller shown at the top of the stack) and then transitions back to a regular size class, we get a crash with the following: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <UINavigationBar: 0x1038e3a40; frame = (0 -102; 834 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000d586f0>; layer = <CALayer: 0x6000003690e0>> delegate=0x105809800 standardAppearance=0x600002662940 scrollEdgeAppearance=0x600002661620, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x103b2bb10> titleView=0x1039b1a70 style=navigator rightBarButtonItems=0x6000000427e0 largeTitleDisplayMode=never searchController=0x1068c1a00 preferredSearchBarPlacement=stacked, navigation bar = <UINavigationBar: 0x103b452c0; frame = (0 24; 834 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000cd7d20>; layer = <CALayer: 0x600000316700>> delegate=0x104898400 standardAppearance=0x60000265ea00 scrollEdgeAppearance=0x60000265fd80, possibly from a client attempt to nest wrapped navigation controllers.' *** First throw call stack: ( 0 CoreFoundation 0x0000000180491128 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x000000018008412c objc_exception_throw + 56 2 Foundation 0x0000000180d1163c _userInfoForFileAndLine + 0 3 UIKitCore 0x00000001848d2510 -[UINavigationBar layoutSubviews] + 472 4 UIKitCore 0x0000000185806d78 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1492 5 UIKitCore 0x00000001848d21d8 -[UINavigationBar layoutSublayersOfLayer:] + 188 6 QuartzCore 0x0000000189ffa5b0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 440 7 UIKitCore 0x00000001857f6260 -[UIView(Hierarchy) layoutBelowIfNeeded] + 292 8 UIKitCore 0x0000000184b147f8 -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] + 584 9 UIKitCore 0x0000000184b149b0 -[UINavigationController _positionNavigationBarHidden:edge:] + 264 10 UIKitCore 0x0000000184b163dc __64-[UINavigationController _setNavigationBarHidden:edge:duration:]_block_invoke + 404 11 UIKitCore 0x0000000184b1603c -[UINavigationController _setNavigationBarHidden:edge:duration:] + 488 12 UIKitCore 0x0000000184b14518 -[UINavigationController setNavigationBarHidden:animated:] + 92 However, if we do not hide the navigation bar in the primary view: no crash. Likewise, if there isn't a second controller pushed onto the navigation stack (meaning no back button is shown), there is no crash, even if the navigation bar is hidden in the primary view. This structure has been fine for over three years and the problem only began with iPadOS 17 building under Xcode 15. I have found similar mentions on other forums, but no real solution. I realize I should probably file a feedback. Unfortunately, past experience has shown that it is a good way to waste countless hours gathering information, creating sample projects that distill the bugs down to their core, only to be met with complete and utter silence. I've lost all confidence in that system and I'm hoping someone else who has run into this may have a workaround or at least some suggestions for things to try.
3
0
1.6k
Jan ’24
Using TipKit in a UIKit/SwiftUI hybrid application
Context: I maintain an app that has a UITabBarController at its root, and the tabs are UIHostingControllers to (mostly) SwiftUI views. I have a UINavigationController I present from that tab bar controller, and the rootViewController of that presented nav is a UIHostingController with SwiftUI views inside (not using NavigationView in there, but I am using .toolbar and NavigationLink). I'm trying to use TipKit in this presented SwiftUI view, and its led to a couple unexpected issues: When I dismiss a tip, the entire presented view controller hierarchy is dismissed (like calling window.rootViewController.dismiss()) somehow, configuring the tooltip inside of a ButtonStyle resolves this issue When I show a tip pointing at a Button inside of the .toolbar sometimes that tip is presented in the top left corner of the window, not pointing to the view properly when the tip is dismissed, that button then stops calling its action and does nothing Has anyone else experienced this/anything like it? Because of this (and other issues from the past) I get the sense that Apple is of the mind that you should either have a fully UIKit application, or a fully SwiftUI application, since issues with bridging between the two are not uncommon and solutions are unclear/undocumented. Curious what others think about this, and about maintaining UIKit/SwiftUI hybrid apps in general.
1
1
972
Jan ’24
UITextView giving wrong UITextPosition with closestPosition on iOS 17 with custom arabic font
Hi, I have used some custom Arabic fonts in UITextView to render some Arabic fonts. On iOS 17 the following code is not giving me the correct position of the tapped text in some special cases. Following the code i am using with the TapGestureRecognizer. @objc func arabicTextViewTapped(_ sender: UITapGestureRecognizer) { let attributedString = NSMutableAttributedString(attributedString: arabicTextView.attributedText) attributedString.removeAttribute(.backgroundColor, range: NSRange(location: 0, length: attributedString.length)) let touchPosition = sender.location(in: sender.view) guard let textPosition = arabicTextView.closestPosition(to: touchPosition), let textRange = arabicTextView.tokenizer .rangeEnclosingPosition(textPosition, with: .word, inDirection: .init(rawValue: 1)) else { return } guard let text = arabicTextView.text(in: textRange) else { return } } In the image below if there is some special character (called Ramos e aukaf) as the first character (which in this case is the small first character on the second line) then this code gives the position on the first line. guard let textPosition = arabicTextView.closestPosition(to: touchPosition) In the below case, the above code works perfectly fine as small character is not the first character on the second line. Also this is only happening on ios 17. Any help is highly appriciated.
0
0
673
Jan ’24