ZStack - IOS 14 beta - Zstack fly on the keyboard - swiftui

In new IOS 14 beta i use ZStack to display badge on my tabs. When keyboard is appear - zstack fly on the keyboard, but it must be fixed in the bottom. IOS 13 - has nothing like this.
ZStack {
Circle()
.foregroundColor(.red)
Text("\(self.realm.ItemsAll.count)")
.foregroundColor(.white)
.font(Font.system(size: 11))
}.frame(width: 15, height: 15)

Related

Text in SwiftUI not using up all the space

I've got a simple Text element, here's the code:
Text("W-XYZ LAB IS CARBON NEUTRAL")
.foregroundColor(.white)
.frame(width: elementWidth, alignment: .leading)
.font(.system(size: 25, weight: .bold))
.padding(.bottom)
.border(.red)
elementWidth = screen width / 1.25
Take a look at the screenshot below:
The text in the Text view does not take up all the space. The word "CARBON" can fit in the first line of the text view but for some reason it goes to the second line. How can I fix this?

Align View to Time on WatchOS using SwiftUI

I'm trying to align a view in SwiftUI the same way the new Workouts app for WatchOS 9 aligns with the time.
I have found this StackOverflow thread, but it does the exact opposite, I need alignment in the vertical axis.
So far I've tried the following, but it does not work for every screen size:
VStack(alignment: .leading) {
// my content here
}
.frame(maxWidth: .infinity, alignment: .leading)
.ignoresSafeArea(edges: [.bottom, .top]).scenePadding().focusable()
(red lines added by me to illustrate)

how to insert a custom image as a navigationBarItem in swiftui

I'm trying to use an image in my Assets to be a navigation bar Item like this:
navigationBarItems(leading: Button(action:{
self.presentMap = true
}) {
Image("map_pin")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 34, height: 34)
}
I works unfortunately the image is masked by a solid color so I only see the shape.
Is there a simple way to just display the image as is?
You need to add the modifier renderingMode(.original) This stops the overlay of the solid color blue.
Image("map_pin")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 34, height: 34)
Or you can add the following modifier to your button .buttonStyle(PlainButtonStyle())
Button(action:{
self.presentMap = true
}) {
Image("map_pin")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 34, height: 34)
}.buttonStyle(PlainButtonStyle())
Check out this article by Paul Hudson https://www.hackingwithswift.com/quick-start/swiftui/how-to-disable-the-overlay-color-for-images-inside-button-and-navigationlink
The difference is subtle, but important: if you are using a Button
inside a List, using .buttonStyle(PlainButtonStyle()) will mean that
only the space directly around the button’s content can be tapped,
whereas if you use .renderingMode(.original) then the whole cell
remains tappable

SwiftUI overlay cancels touches

I have a button and I'd like to put a semi-transparent gradient overlay on top of it.
Button(action: {
print("Pressed")
}) {
Text("Press me")
}
.overlay(
LinearGradient(
gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
startPoint: .top,
endPoint: .bottom
).disabled(true)
)
Even though the gradient has disabled(true) it still eats the touches and doesn't forward them to the actual button. .allowsHitTesting(false) provides the same result.
Any idea what can be wrong?
Note: I know I can put the overlay just to Text("Press me") but I don't want it. (This is just example code showcasing the problem)
Edit: This issue is solved in Xcode 11.2 ✅
The following code works on Xcode 11.2 / iOS 13.2
struct TestButtonWithOverlay: View {
var body: some View {
Button(action: {
print("Pressed")
}) {
Text("Press me")
.padding()
}
.overlay(
LinearGradient(
gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
startPoint: .top,
endPoint: .bottom
)
.allowsHitTesting(false) // !!! must be exactly here
)
}
}
When working with a ScrollView the correct fix is to use the .background content modifier on the ScrollView:
https://developer.apple.com/documentation/swiftui/form/background(alignment:content:)
It will as expected with your "background" appearing above the content of the ScrollView.
Example of using to create a shadow effect:
Interesting note: On the simulator .overlay works with a ScrollView, but on a physical device only .background allows scrolling.
The physical device is on iOS 14, and the simulator is iOS 15, so it's possible it might have been a regression. Although apparently this issue dates back further than either.

Text has only one line when put in HStack with something else (SwiftUI List)

im trying to show a list of items. Every row should contain a stripe on the left in a specific color and a headline. This headline is sometimes more than a line long but only shows as one line and "...". When I remove the Stripe it shows as multiline text. I've attached the code and two pictures for comparison
Heres my code :
HStack {
Rectangle()
.foregroundColor(poll.outcome ? .green : .red)
.frame(width: 3)
VStack {
Text(poll.poll.title!).font(.headline)
.lineLimit(2)
}
}
This is how it looks without the Rectangle:
And with the Rectangle:
In a List or ScrollView the SwiftUI engine will compress back the text area. .lineLimit(x) give you a maximum of line, not a minimum ;)
To secure that the engine does not shrink back the Text height and goes up to the maximum limit, add .fixedSize(horizontal: false, vertical: true) as shown below
HStack {
Rectangle()
.foregroundColor(.red)
.frame(width: 3)
VStack {
Text("line1\nline2\nline3").font(.headline)
.lineLimit(2)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
}
}
SwiftUI has some bugs right now and it is one of them and there is some discussion on this answer that you can check out.
Although It works on my machine, if you have any trouble about sizing elements, you can use Spacers as a workaround until all SwiftUI bugs fix by Apple.
For this case, you can wrap your text between two spacers like this:
VStack {
Spacer()
Text("FirstLine\nSecondLine\nThirdLine")
.font(.headline)
.lineLimit(2)
Spacer()
}