So currently what I have been doing for determining what device type and orientation I am in for SwiftUI is using sizeClasses, usually something like the following:struct SizeClassView: View {
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
var body: some View {
if horizontalSizeClass == .compact && verticalSizeClass == .regular {
Text("iPhone Portrait")
}
else if horizontalSizeClass == .regular && verticalSizeClass == .compact {
Text("iPhone Landscape")
}
else if horizontalSizeClass == .regular && verticalSizeClass == .regular {
Text("iPad Portrait/Landscape")
}
}
}What I'd like to know is: Is there any better way to do this in SwiftUI? The main problem I'm having with this method is that I can't differentiate between iPad Portrait and Landscape, but at least I can use it to differentiate between iPhone Portrait and iPhone Landscape and iPad... Any help and insight is greatly appreciated!
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Post
Replies
Boosts
Views
Activity
Hi all!When presenting a specific modal sheet in a SwiftUI project, I consistently get a ton of console output like:=== AttributeGraph: cycle detected through attribute 290 ===Like, a couple hundred of these logs. It appears to be accompanied by a stutter/slowdown in the UI, but there's no crash and everything looks to be in the right place.Is the "cycle" here some sort of ARC retain cycle? Is it SwiftUI-specific? (I'm asking here because I've never seen this warning in a classic UIKit project.) Where can I go to learn more about this?Thanks!
I want to switch from a running CarPlay appto another CarPlay app without going through CarPlay HOME.I have tried openURL using URL scheme.As a result, the app started on the smartphone,but the app on the Simulator did not switch.I would like to know the URLif there is official information on CarPlay application switching.
I've been getting occasional crash reports that look similar to this:Fatal Exception: NSInternalInconsistencyException
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x19dcd0a48 __exceptionPreprocess
1 libobjc.A.dylib 0x19d9f7fa4 objc_exception_throw
2 Foundation 0x19e1a6f08 -[NSISEngine tryToOptimizeReturningMutuallyExclusiveConstraints]
3 Foundation 0x19dfa803c -[NSISEngine withBehaviors:performModifications:]
4 UIKitCore 0x1a20ff8e8 -[UIView(UIConstraintBasedLayout) _resetLayoutEngineHostConstraints]
5 UIKitCore 0x1a21d9314 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
6 QuartzCore 0x1a473c7dc -[CALayer layoutSublayers]
7 QuartzCore 0x1a4742958 CA::Layer::layout_if_needed(CA::Transaction*)
8 QuartzCore 0x1a474d578 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
9 QuartzCore 0x1a4695f1c CA::Context::commit_transaction(CA::Transaction*, double)
10 QuartzCore 0x1a46bfc08 CA::Transaction::commit()
11 QuartzCore 0x1a46c0b8c CA::Transaction::release_thread(void*)
12 libsystem_pthread.dylib 0x19d9eefb0 _pthread_tsd_cleanup
13 libsystem_pthread.dylib 0x19d9ebde8 _pthread_exit
14 libsystem_pthread.dylib 0x19d9ece7c _pthread_wqthread_legacy_worker_wrap
15 libsystem_pthread.dylib 0x19d9ecc18 _pthread_wqthread
16 libsystem_pthread.dylib 0x19d9ef760 start_wqthreadThis is not being invoked by my code (at least directly). I've been running the app in the debugger with the Main Thread Checker enabled and have yet to catch whatever is causing this.I've found multiple reports from others who have been experiencing similar issues, most commonly on iOS 13. (My app only supports 13 and later.) I have yet to see any solid explanation. @Eskimo - is it possible that iOS is invoking something that results in a UI state change which is called from a background thread?Thanks,-S
I think I've found a bug with focusable(_: onFocusChange:) on MacOS with SwiftUI and wanted to sanity check it here before using feedback assistant. This is with Xcode 11.3.1When I create the window, the VStack inside thinks it is in focus. But the onFocusChange closure never gets called to say it loses focus. As a result, both my VStacks in both my windows think they are infocus.Demonstration project at https://github.com/darrellroot/focusBug/Here's my ContentView which displays whether it thinks it is in focus:struct ContentView: View {
@State var inFocus = false
let windowCount: Int
var body: some View {
VStack {
Text("Focus Window \(windowCount)")
inFocus ? Text("This window thinks it is in focus") : Text("This window does not think it is in focus")
}.padding(50).focusable() { newFocus in
debugPrint("onFocusChange: \(newFocus)")
self.inFocus = newFocus
}
}
}Here's my appDelegate code which spawns 1 window on launch and 1 more every time a particular menu is selected: var windows: [Int:NSWindow] = [:]
var windowCount = 0
func applicationDidFinishLaunching(_ aNotification: Notification) {
newWindow()
}
@IBAction func newFocusWindow(_ sender: NSMenuItem) {
newWindow()
}
func newWindow() {
windowCount = windowCount + 1
let contentView = ContentView(windowCount: windowCount)
let window = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 1000, height: 1000),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.isReleasedWhenClosed = false
windows[windowCount] = window
window.title = "Focus Window \(self.windowCount)"
window.tabbingMode = .disallowed
window.center()
//window.setFrameAutosaveName("Window \(self.windowCount)")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
}DebugPrint output shows that onFocusChange got called once per window:2020-03-09 10:24:22.363001-0700 focusBug[2555:258395] Metal API Validation Enabled"onFocusChange: true""onFocusChange: true"
How can I can the localized string for the month, day, week units. I'm not speaking about "january", "february"... But the localized word "Month". Is the only solution is to do this by hand with NSLocalizedString?
I have an editor view that's broken up into several subviews. The model is a relatively small struct, but it does have a couple properties that can be variable-length arrays.The problem I'm having is after I add one entry to any one of these arrays, the view stops updating:struct ChecksView: View {
@Binding var checks: [Check]
var body: some View {
HStack(alignment: .top, spacing: 0) {
Button("add prereq", action: {
self.checks.append(Check())
})
VStack {
ForEach(self.checks.indices, id: \.self) { i in
CheckView(check: self.$checks[i])
}
}
}
}
}In this subview, the first time you tap "add prereq", it will add to the array & update the UI. But every subsquent time, nothing updates until you navigate away & return. What am I doing wrong?
Does anyone know if there is a way to move the "Maps" and "Legal" text in the Map SwiftUI view? App Store Guidelines require that the text be shown, but if you are trying to add some type of sheet or view overlay for some of the map, I can't seem to find a way to add extra bottom padding to this text.
I'd like to emulate the behavior of UIViewController.isModalInPresentation in SwiftUI. In my first attempt, I defined the following view:
struct ModalView<Content: View>: UIViewControllerRepresentable {
		var content: () -> Content
		func makeUIViewController(context: Context) -> UIHostingController<Content> {
				let controller = UIHostingController(rootView: content())
				controller.isModalInPresentation = true
				return controller
		}
		func updateUIViewController(_ imagePickerController: UIHostingController<Content>, context: Context) {}
}
From my main app view, I then present the ModalView as a sheet:
struct ContentView: View {
		@State
		var presentSheet: Bool = true
		var body: some View {
				Text("Hello, world!")
						.sheet(isPresented: $presentSheet) {
								ModalView {
										Text("Sheet")
								}
						}
		}
}
But the user is still able to dismiss the ModalView by swiping down. I would expect this sheet to be non-dismissible. Is anything like this supposed to work? If not, is there some other way to prevent the dismissal of a sheet in SwiftUI?
The closest workaround I've found is to apply .highPriorityGesture(DragGesture()) to the content of the sheet, but swiping down with two fingers still works.
How do I hide the separation lines inside Lists in SwiftUI for iOS 14?
Previously I could use
UITableView.appearance().separatorStyle = .none
but this doesn't seem to work anymore.
I wonder where can I find source of ShapeEdit app mentioned in the WWDC 2020 SwiftUI videos. All I can find is old ShapeEdit.
I keep getting a Xcode Previews error in Xcode 12 from a package that imports other packages. As soon as I remove the dependency I'm able to see the SwiftUI preview. I'm only able to use previews in packages that have no dependencies
The error I get is: "LoadingError: failed to load library at path...Library not loaded " then it point to the dependency that it could not load in the current package.
How can I access Xcode Previews from a package that depends on other packages?
I have two (local) Swift packages (both with a single library product): RemoteImage, which defines setImage(from:) function on UIImageView and SatelitUI package which directly depends on the first one and defines some views. But when I'm trying to preview views from the second package I'm getting the following error:
linker command failed with exit code 1 (use -v to see invocation)
LinkDylibError: Failed to build TrailerView.swift
Linking failed: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: directory not found for option '-F/Applications/Xcode-beta.app/Contents/SharedFrameworks-iphonesimulator'
Undefined symbols for architecture x86_64:
"(extension in RemoteImage):__C.UIImageView.setImage(from: Foundation.URL?) -> ()", referenced from:
(extension in SatelitUI_PreviewReplacement_TrailerView_2):SatelitUI.TrailerView.(previewupdate in _8C3731B0EF007627509BEEB93277D681)(with: SatelitUI.Trailer?) -> () in TrailerView.2.preview-thunk.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Apparently, Xcode fails to link the library from the first package because it's dynamic. Static linking works as expected.
It's a bug I believe?
I'm facing a weird situation in my app. When keyboard shows up and I click on microphone icon for dictation, the "Enable Dictation?" alert shows up but disappears quickly before I can tap on any option. How do I find out what is wrong in my code or how do I fix it?
In a simple app with a ScrollView inside a NavigationView, on scroll the content of the scrollView doesn't smoothly transition from its size with navigationBarDisplayMode .large to .inline, but rather makes this a jarring jump.
Minimum code to reproduce:
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
ForEach(0..<200, id: \.self) { i in
Text("Row \(i)")
.frame(maxWidth: .infinity)
}
}
.navigationTitle("Test")
}
}
}
The following code produces the desired smooth transition though:
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(0..<200, id: \.self) { i in
Text("Row \(i)")
}
}
.navigationTitle("Test")
}
}
}
I could not replicate the issue using UIKit's UITableViewController inside a UINavigationViewController, nor with a UIScrollView inside a UINavigationViewController.
Observed in simulator and on device running iOS 14 public beta (18A5319i), built with Xcode 12.0 beta 2 (12A6163b) on macOS 10.15.5 (19F101).
I have the new iOS 14 VideoPlayer:
private let player = AVPlayer(url: Bundle.main.url(forResource: "TL20_06_Shoba3_4k", withExtension: "mp4")!)
		var body: some View {
								VideoPlayer(player: player)
								.aspectRatio(contentMode: .fill)
...
This player setup can not display 4:3 video on 16:9 screen of tv without black stripes. Modifier aspectRatio does not work on VideoPlayer.
How can I set videoGravity of existed AVPlayerLayer to resizeAspectFill via SwiftUI API?
I need a scrolling view to report when it's scroll/drag gesture ends.
Here's a simple SwiftUI example taking a basic approach:
import SwiftUI
struct CarouselView: View {
let colors: [Color] = [.red, .green, .blue]
var drag: some Gesture {
DragGesture()
.onChanged { state in
print("changing")
}
.onEnded { state in
print("ended")
}
}
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(0..<10) { i in
Text("Block \(i)")
.frame(width: 300, height: 300)
.background(colors[i % colors.count])
.id(i)
}
}
}
.gesture(drag)
}
}
The gesture's events properly fire when you drag vertically, but when you drag horizontally (matching the direction of the scroll view) only the first onChanged event fires.
I don't want to even begin trying to reimplement a ScrollView in SwiftUI just to get these events, but is there a better way?
I have a NSTableView under a NSViewRepresentable and I'm trying to add a new row when the + button is clicked.
With the code below, the ForEach statement is updated when the data is added to the state variable, but the table view doesn't show the new element.
Why is that?
import PlaygroundSupport
import SwiftUI
struct TV: NSViewRepresentable {
@Binding var students: Array<String>
func makeNSView(context: Context) -> NSScrollView {
let sv = NSScrollView()
let tv = NSTableView()
sv.documentView = tv
tv.gridStyleMask = .solidHorizontalGridLineMask
tv.usesAlternatingRowBackgroundColors = true//
tv.allowsMultipleSelection = true
let col = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "Name"))
col.title = "Name"
_ = tv.addTableColumn(col)
_ = tv.delegate = context.coordinator
tv.dataSource = context.coordinator
return sv
}
func updateNSView(_ nsView: NSScrollView, context: Context) {
(nsView.documentView as! NSTableView).reloadData()
}
func makeCoordinator() -> Coordinator {
Coordinator(self, students: self._students)
}
class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource {
var parent: TV
@Binding var students: Array<String>
init(_ parent: TV, students: Binding<Array<String>>) {
self.parent = parent
self._students = students
}
func numberOfRows(in tableView: NSTableView) -> Int {
return students.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
print(students[row])
return students[row]
}
func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool {
return true
}
func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int) {
self.students[row] = object as! String
}
}
}
struct view: View {
@State var students = ["John", "Mary", "Bob"]
@State var minusDisabled: Bool = true
var body: some View {
Group {
VStack(alignment: .leading) {
Text("Test")
TV(students: self.$students).frame(width: 400, height: 300)
HStack {
Button(action: {
self.students.append("New Row")
}) {
Text("+")
}.buttonStyle(BorderedButtonStyle())
Button(action: {
}) {
Text("-")
}.buttonStyle(BorderedButtonStyle())
.disabled(self.minusDisabled)
}
}.fixedSize()
ForEach(self.students, id: \.self) { student in
Text(student)
}
}
}
}
PlaygroundPage.current.setLiveView(view().frame(width: 500, height: 800))
I needed an infinite canvas for my app which is basically a drawing board where one can draw things using pen.
So, I thought of having a very large custom UIView inside a UIScrollView. And in the custom view, I could keep drawing things. But, I ended up with a warning saying something like below and nothing drawn on screen.
[<CALayer: 0x5584190> display]: Ignoring bogus layer size (50000, 50000) Which means, I can't have such a big CALayer to draw things. Now, solution? alternative? Then comes CATiledLayer. I made my large UIView backed by CATiledLayer now. After having a proper levelOfDetails and levelOfDetailsBias value, things worked like charm. Until I ended up facing another problem.
Since, CATiledLayer caches drawing in different zoom levels if I try to scale the view after changing the drawing content the cached drawings appear and then the new contents get drawn.
I don't find an option to invalidate caches in different levels. All the solutions I came across leads me to clear the entire contents of the CATiledLayer on drawing content change which won't help again.
Do I miss something here? Is there a way with which I can clear caches at different levels? Or is there any other solutions which could solve my need? Can someone help me with this?
Hi,
I'm testing one of my app on iOS 14 with Xcode 12 beta 3 (12A8169g) and I have a problem with my storyboards.
Xcode give me this error for all the storyboards that contain a split view controller:
An internal error occurred. Editing functionality may be limited.
The log generated by the Xcode "Report a bug" button say:
Exception name: NSInvalidArgumentException
Exception reason: UITabBarController is unsupported as viewController for -[UISplitViewController setViewController:forColumn:] in Primary column
It worked correctly on Xcode 12 beta 2.
Has anyone encountered the same problem and found a way to fix it?
Thank you