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).
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
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 have a ZStack with two nested views. They are both the same type, RowView, and each RowView has another ZStack and a Text.
Both of these RowViews have the same height for some reason. And when I replace the RowView ZStack with just a Text, it works correctly.
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView {
&#9;&#9; // remove this ZStack and things work with the other nested ZStacks
ZStack {
Rectangle()
.foregroundColor(.blue)
.shadow(radius: 5, x: 5, y: 5)
VStack {
// Two independent RowViews:
RowView(title: "Some really long text for some stuff lollola really long text for some stuff lollola")
RowView(title: "and more")
}
}
.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct RowView: View {
@State var title: String
let boxSize: CGFloat = 40
var body: some View {
HStack(alignment: .top, spacing: nil) {
Rectangle()
.foregroundColor(.orange)
.frame(minWidth: boxSize,
maxWidth: boxSize,
minHeight: boxSize,
maxHeight: boxSize)
.padding(5)
// this has each RowView set its own height correctly
// Text(title)
// .multilineTextAlignment(.leading)
// .padding(5)
// this forces both RowViews to have the same height, even though they are separate from each other
ZStack {
Rectangle()
.foregroundColor(.gray)
Text(title)
.multilineTextAlignment(.leading)
.padding(5)
}
.padding(5)
// this also forces both RowViews to have the same height
// Rectangle()
// .foregroundColor(.gray)
// .overlay(Text(title).padding())
// .padding(5)
}
}
}
It seems strange that both independent RowViews will end up having the same height.
Read the release notes and didn't see mention of this being a possible bug.
Copy pasta and see the results if you'd like. Notice the Gray ZStack containers are all almost the same height? Make the test of the first row even longer. Notice how the second one increases it's height?
Is this a bug,? Are ZStacks never supposed to be nested?
I have recently created a pure (admittedly simple) SwiftUI app for iOS/iPad. Yes there are bugs and limitations I've had to face but eventually with a certain amount of compromise and without resorting to UIViewRepresentable, it works adequately.
Great, I thought, how hard can it be to create a macOS version of the same app? Take TextField (swiftUI) views which my app depends on a lot, the issues I have found have been numerous...
TextField does not appear to update the Binded variable after each character is typed in. You have to hit the return key for it to register. Totally different functionality.
Placeholder text shifts up a few pixels when it gets keyboard focus.
The rectangle where the text is typed needs to be taller holding the text, currently it looks squashed.
Manually adding a ‘clear text’ button on top of the TextField (at the right) appears not to to be active when the cursor is over it (most of the time)
Lots of missing autocapitalisation type functionality is missing.
I could go back to a NSViewRepesentable solution of the TextField but that negates the use of 'supported' SwiftUI features. Has this half baked feature been pushed out there as a 'tick in the box' option or is Apple genuinely happy with their solution?
Anyhow, I thought let's do a MacCatalyst version of my App instead. But we get a TabView looking like a iPad/iPhone App, there is no option to make it look more mac like AFAIS without abandoning TabView itself!
Then there's the complication of making my Core Data App work as a 'Document Based' app with the new DocumentGroup/Scene solution.... how does NSPersistentDocument work in such scenarios? The documentation is vague at best, or simply not supported without a lot of workarounds.
Just these few things make me feel we are being hyped with solutions which are far too premature for any real world work on macOS at the moment.
What potential SwiftUI/macOS blockers have you encountered?
In WatchOS 6 a presented .sheet could be dismissed by swiping down or tapping on the navigationBarTitle. In the WatchOS 7 beta, presented sheets are no longer dismissible by either method...forcing the addition of a button to dismiss.
It appears as if .sheet is now acting as .fullScreenCover within WatchOS 7.
Anyone else running into this? Wondering if this is now expected behavior on WatchOS or if it's a bug...
I am presenting a sheet using the view modifier
.sheet(item: ...)
if the view you are presenting is wrap inside another view which only add a navigation view
let's say I have a view called ViewB with a dismiss button which called the presentation mode dismiss, that works
let' say I have another view called ViewBWithNavigationView
where it's calling ViewB inside the NavigationView and it also calling dismiss on the cancel button
the result of this is that the presentation mode dismiss will only works for the first view B the cancel button, it will no close the view if you click the button inside the view
struct ViewBInsideNavigationView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
ViewB()
.navigationBarTitle("View B", displayMode: .inline)
.navigationBarItems(leading: Button("Cancel") {
self.presentationMode.wrappedValue.dismiss()
})
}
}
}
the call to self.presentationMode.wrappedValue.dismiss() inside ViewB is not trigger and the view is not dismiss
thanks
The two property wrappers @AppStorage and @SceneStorage are great because you can simply redeclare a property in multiple views to share the value and automatically update other views.
But how should I access those same values outside of views?
I have helper functions which are used in multiple views and which change behaviour based on those stored properties. I believe I could use the old NSUserDefaults.standard to reference the @AppStorage values, but is that the "right" way to do it, and how do I access @SceneStorage values?
Sometime, when I open the Widget Gallery, function getSnapshot(for:in:completion:) in TimelineProvider is not called. Is this a feature or a bug? When is this function called?
Thank you.
Can anyone confirm that there is at present no equivalent on the TextField view to the UITextFieldDelegate method
textField(_:shouldChangeCharactersIn:replacementString:)
i.e. one that can intercept each keystroke and and paste to ensure that the value is always valid?
In SwiftUI the onEditingChanged parameter in the constructor is not triggered with each character entered.
In the following environment: iOS 14 beta, Xcode Version 12.0 beta 6 (12A8189n) try to implement user Apple Login with Firebase. Works until password entering screen and then hangs up on simulator or finished with error on device. Sign In with Apple is enabled in App.
Any help with preview crash on an App that is building just fine and runs on simulator fine?
Are there logs that I can access somehow?
The previews were working just fine, but then stopped and I have reverted all changes since and the previews are still broken.
(Cross post from: Stack Overflow - https://stackoverflow.com/questions/64096402/swiftui-preview-sheet-w-o-running-live-preview)
Is it possible to create a SwiftUI preview of a presented sheet without running the Live Preview? For example:
struct Sheet_Previews: PreviewProvider {
static var previews: some View {
Text("Background").sheet(isPresented: .constant(true)) {
Text("Sheet")
}
}
}
The above results in the following preview:
(See image 1 on Stack Overflow - https://stackoverflow.com/questions/64096402/swiftui-preview-sheet-w-o-running-live-preview)
In order for the sheet content to be presented in the preview, you must run the Live Preview:
(See image 2 on Stack Overflow - https://stackoverflow.com/questions/64096402/swiftui-preview-sheet-w-o-running-live-preview)
Hello,
I'm trying to remove the current back button behavior in a navigation view and instead have a simple arrow.
Disabling the button with navigationBarBackButtonHidden and then adding my own with navigationBarItems works, but then I lose the swipe gesture to go back. I could try to rebuild this swipe gesture, but that seems hard to get the same feel, and it will most likely break often.
Is there something simpler ?
I'd be satisfied with just removing the text of the back button and keeping only the <.
Thanks
Repro steps: Create new project
Create WidgetKit extension (verify that previews work)
Create dummy framework (verify that previews still work)
Link dummy framework to the widget extension
At that point, preview stops working with the following error:
"RemoteHumanReadableError
ProcessError: Failed to launch widget extension: The operation couldn’t be completed. (CHSErrorDomain error 1050.)"
What can I do to make this work?
I'm trying to make a gradient for Widgets and using 2 blue colors (#0091f1 and #0054f3) but the Widget background looks green.
I've set up colors via Assets.xcassets and then using the following code:
LinearGradient(gradient: Gradient(colors: [Color("color1"), Color("color2")]), startPoint: .top, endPoint: .bottom)
For the common iOS target the gradient looks right (blue) and for the Widgets extension it's green.
Could you help me to figure out why this is happening?
The link - https://github.com/maximbilan/SwiftUI-WidgetKit-Gradient-Issue to the example with screenshots.
Hey there!
Got a question about font kerning:
When adding a negative kerning to a text (changes via user input) the last character sometimes gets cut off:
dropbox.com/s/49ucdzk8m4k61sj/fontproblem1.png?dl=0
dropbox.com/s/vmklvxp510wjeak/fontproblem2.png?dl=0
What i do is the following:
Text("\(pos, specifier: "%.1f")")
	.font(.system(size: 100,design: .serif))
	.fontWeight(.bold)
	.kerning(-5)
When i remove the kerning it works, but as i understood the kerning keeps the letters as they are? Is there an alternative way of doing it?
I'm trying to create a custom Picker similar to the one in the Reminders app where users can select colors and icons for a list of reminders.
I currently have this:
struct CustomPickerStyle: PickerStyle {
static func _makeView<SelectionValue>(value: _GraphValue<_PickerValue<CustomPickerStyle, SelectionValue>>, inputs: _ViewInputs) -> _ViewOutputs where SelectionValue : Hashable {
}
static func _makeViewList<SelectionValue>(value: _GraphValue<_PickerValue<CustomPickerStyle, SelectionValue>>, inputs: _ViewListInputs) -> _ViewListOutputs where SelectionValue : Hashable {
}
}
These are automatically generated by Xcode. How should I deal with these methods? I could not find any documentation online for making a custom picker view...
Thanks!
I have a starting view that contains the StateObject created from an Observable Object.
struct PostLoginView: View {
@StateObject var userLoader = FirestoreUser(uid: Auth.auth().currentUser!.uid, getUpdates: true)
var body: some View {
TabView(selection: $currentTab) {
NavigationView{
UserProfileView(currentTab: $currentTab, userLoader: userLoader, postsLoader: postsLoader)
.environmentObject(userSettings)
}
This gets passed to other views where it is observed.
struct UserProfileView: View {
@ObservedObject var userLoader: FirestoreUser
Group{
HStack {
Spacer()
NavigationLink(destination: ProfilePhotoUpdateView(userLoader: self.userLoader).environmentObject(self.userSettings)) {
Image(systemName: "pencil").padding(.horizontal).font(Font.title.weight(.bold))
.foregroundColor(buttonStartColor)
}
}
This chain can continue for a few more links
If the model userLoader is updated in any way, the stack pops back automatically to the first view. This is not the desired behavior. How can I keep the current child view when the model is updated?