SwiftUI different behavior on different iOS versions - ios

I have been developing an app with minimum iOS 13, but whole development process was done on iOS 15. Now when testing the iOS 13 devices, I noticed some problems.
Minimalistic example: You have a list of items, where each item contains leading icon, with a title and a subtitle vertically stacked. To adapt to various screen sizes, I attached a .minimumScaleFactor() to the texts so they would scale down when needed. That's working nicely on iOS 15. After a whole lot of testing, it also works on iOS 13.4 that is the oldest where I've got it working, so, iOS 13 - <13.4 is in question here.
On the screenshot you can see iPhone 8 13.3 vs iPhone 8 13.4, the text is scaled down even when there is space available. On iPhone 6s Plus 13.3 there is even more available space (screen size).
And the code:
struct Viewwww: View {
var title = "This is a title This is a title This is a title This is a title This is a title "
var subtitle = "This is a subtitle This is a subtitle This is a subtitle This is a subtitle This is a subtitle "
var body: some View {
VStack{
Text("Onboarding test").font(.title).multilineTextAlignment(.center).lineLimit(2)
Spacer()
buildItem()
buildItem()
buildItem()
buildItem()
buildItem()
Spacer()
}.padding(.horizontal, 20)
.padding(.top, 30)
}
#ViewBuilder
func buildItem() -> some View {
HStack(alignment: .top, spacing: 20){
VStack {
Image(systemName: "pin").resizable().scaledToFit().frame(width: 44, height: 44)
}
VStack(alignment: .leading, spacing: 10){
Text(title).font(Font.title).minimumScaleFactor(0.5)
Text(subtitle).font(Font.body).minimumScaleFactor(0.5)
}
Spacer()
}.frame(maxWidth: .infinity).background(Color.red)
}
}
So anyone has experienced this, and can help? Thank you!

Related

SwiftUI - RTL device languages don't display the expected RTL layout

The following code:
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, world!")
.padding(.leading, 150)
HStack {
Spacer()
.frame(width: 16)
Image(systemName: "pencil.circle.fill")
.resizable()
.frame(width: 100, height: 100)
Spacer()
}
}
}
}
looks like this when the system and app languages are set to a LTR language:
Oddly, if I set the device language to Arabic the layout is unchanged, it appears the same as English. The same problem if I set the app language to Arabic in "Edit scheme..." in Xcode.
However, if I set the app language to "Right-to-Left pseudolanguage" the layout is as expected for a RTL language:
Why is the expected RTL layout not shown when I set the device or app language to Arabic? How can I make my app display correctly on devices set to a RTL language?

In a SwiftUI VStack how do I make multiple Text Views, each with multiple lines of text, the same width

I'm trying to make the text in the VStack the same width but don't know how. I saw it suggested elsewhere to set a frame maxWidth to .infinity for each of the Text Views but it doesn't have any effect when I try it in my code.
This is the code I have:
struct ContentView: View {
var body: some View {
VStack(alignment: .center, spacing: 8.0) {
Spacer()
Text("Youngsters can play in Kids mode. If you're feeling very adventurous you can play in BigKids mode.")
.padding(.horizontal)
Text("Kids mode uses large images and big differences between the number of images shown.")
.padding(.horizontal)
Text("BigKids mode, on the other hand, uses small images and small differences between the number of images shown. Go for it!")
.padding(.horizontal)
Spacer()
}
.frame(maxWidth: 600.0)
}
}
I'm using a frame maxWidth of 600 for the VStack as I don't want it wider than that when an iPad is used.
Here's the results of the code. Note that each Text View is a different width.

iOS app blank navigationView opening screen on some device simulators and not others

I've written an app in Swift 5 using XCode 12.2
The app and all it's functionalities work on the following simulators: iPhone 8, iPhone SE 2nd Gen, iPhone 11 Pro, iPhone 12, iPhone 12 Pro, and iPhone 12 Mini
The issue occurs on all iPads, iPhone 8 plus, iPhone 11, iPhone 11 Pro Max, and iPhone 12 Pro Max.
I'm not sure what to make of this and am considering submitting a bug report/TSI, but I wanted to make sure there wasn't an obvious issue with my design.
Below is the structure of my content view. I removed things I though were extraneous to try to concisely illustrate the structure. I've also attached images of the properly running initial view vs the failing one.Proper Opening Screen, Problem opening Screen. I also ran it on a real iPhone SE 2nd gen and iPhone 8 and got the same results.
Thanks in advance.
struct ContentView: View {
//#State vars
var body: some View {
NavigationView{
ZStack{
Image("image")
VStack{
Spacer()
HStack{
Text("text")
.bold()
.foregroundColor(.white)
.font(.largeTitle)
Image("image2")
}.offset(y:10)
Form {
Section(header: Text("INITILIZATION SETTINGS")){
TextField("t1", text: $t1)
TextField("t2", text: $t2)
Stepper(value: $s1, in: 1...240){
Text("s1: \(s1)").onChange(of: s1, perform: { value in
playSound(sound: "sound1", volume: 0.3)
})
}
}
}.frame(minWidth: 0, idealWidth: 400, maxWidth:400, minHeight: 0, idealHeight: 100, maxHeight: 180, alignment: .center).border(Color.black, width: 7)
VStack()
{
NavigationLink(destination: otherView().onAppear{playSound(sound: "sound2")}, label: {
Text("label")
}).padding().background(Color.white).border(Color.black, width: 2).cornerRadius(3.0)
NavigationLink(destination: otherView2()) {
Text("label2").padding(5).background(Color.white).border(Color.black, width: 2).cornerRadius(3.0).offset(y:-5)
}
}
Spacer()
}
}
}.navigationBarTitle("").navigationBarHidden(true)
}
}
The solution was very simple and a matter of settings. Answer at ~29 mins in this Hacking With Swift video [https://youtu.be/nA6Jo6YnL9g?t=1720][1].
Large screen iOS devices automatically split the screen into multiple views with default navigationView{} settings. I don't know what the blank screen was about, but this fixed the problem
Simply add view modifier .navigationViewStyle(StackNavigationViewStyle())
I figured I'd self-answer instead of deleting the post because I had a lot of trouble finding solutions on the web! Hopefully this will be helpful to someone!

How to align text within a SwiftUI ZStack for smaller screen sizes?

I'm attempting to align a Text view within a ZStack. It works fine for larger screens like the iphone 11 plus max but on smaller screens the text will go off screen if I use trailing or leading alignment like below. I get the same result on the preview, simulator and a real SE device.
iPhone SE (2nd gen) Screenshot showing misaligned text for photo attribution text.
import SwiftUI
struct ItemDetail: View {
var item: MenuItem
var body: some View {
VStack {
ZStack(alignment: .bottomTrailing) {
Image(item.mainImage)
Text("Photo: \(item.photoCredit)")
.padding(4)
.font(.caption)
.background(Color.black)
.foregroundColor(.white)
}
Text(item.description)
.padding()
Spacer()
}
.navigationBarTitle(Text(item.name), displayMode: .inline)
}
}
I think your code is good, the problem is that your image is too wide and it's overflowing on the right side of the screen. The text label is aligning correctly to the trailing of the image (that's why it works on bigger devices), not to the trailing of the screen (what you want).
You should make sure your image doesn't overflow.
Image(item.mainImage)
.resizable()
.scaleToFit()
I would use GeomteryReader. Just like that:
GeometryReader { geo in
Text(item.description)
.fixedSize(horizontal: false, vertical: true)
.frame(width: geo.size.width, alignment: .leading)
}

SwiftUI NavigationLink still broken in Xcode 11.4 simulators?

I'm aware of the bug that was supposedly recently fixed in Xcode 11.4, where if you ran a simulator with iOS 13, the back button for a navigation link wouldn't function correctly. I checked that I'm on 11.4, with the following terminal output,
myUser#myUser ~ % /usr/bin/xcodebuild -version
Xcode 11.4
Build version 11E146
and yet I'm still having trouble with the back button from NavigationLink. I don't have access to a real device to test on, but either way this issue was said to have been fixed. Am I setting up the NavigationLink incorrectly?
Here's example code of my setup:
//in primary view
NavigationLink(destination: Test()) {
Text("Hit Me!")
.fontWeight(.semibold)
.font(.title)
.padding()
.foregroundColor(.white)
.background(LinearGradient(gradient: Gradient(colors: [Color(.white),Color(.blue)]), startPoint: .leading, endPoint: .trailing))
.cornerRadius(40)
}
//the view being navigated to
//I can make it to this page but cannot navigate back
struct Test : View {
var body: some View {
Text("Hi!")
}
}
I'm answering my own question in case someone else makes the same small mistake as myself: NavigationView must be the outer most view in your body. I initially had
KeyboardHost { //Custom view class
NavigationView {
VStack {
....
Switching to the following fixed the issue
NavigationView {
KeyboardHost {
VStack {

Resources