How to expand frame by dx,dy in SwiftUI - swiftui

For some reason the Text() view that I create sometimes doesn't fit the string correctly in its frame and instead draws the ellipsis -- while I am not explicitly defining the frame of the view. So I would like to "expand" the frame by a dx/dy amount in the x/y directions -- is there a view modifier that I can use for that? ex. Text(" Jx3 ").expand(dx: +4, dy: 0) Or maybe I'm not supposed to use extra space in the string, but then the background shape is too narrow.
viewForPoints(displayHistory[index].displayPoints)
.overlay(
Text(" \(displayHistory[index].abbreviation) ")
.foregroundColor(.gray)
.font(FONTO)
.offset(x: +8, y: +14)
.background(
Capsule()
.fill(Color.white)
.offset(x: +8, y: +14)
)
)

Try to use fixed size, as
.overlay(
Text(" \(displayHistory[index].abbreviation) ")
.fixedSize()
)
Tested & works with some replicated code with Xcode 11.2 / iOS 13.2
Note: overlay uses same frame as its owner, so probably it worth considering ZStack for your case instead.

Related

Shadow of RoundedRectangle is pixelated on edges

Based on some logic we apply shadow for RoundedRectangle which is the element used in the .background property of the whole VStack.
VStack {
...
}
.background(
RoundedRectangle(cornerRadius: 16, style: .continuous)
.foregroundColor(.white)
.shadow(color: .black,
radius: .zero,
x: 4,
y: 4)
)
The pixelated parts appear on the bottom left and right edges as well as the top right corner.
I did try using different kinds of RoundedRectangle styles (both of them .circular & continuous), but nothing really helped.
Thanks in advance.

How to control height and padding of GeometryReader

I have two Text Fields side-by-side. The first field should take up 25% of the width and the second field 75%. I also have a view modifier that adds 24px of horizontal padding.
Two issues
The second Text Filed does not respect the Horizontal padding on the right side. How do I get it to respect the padding?
The whole Geometry Reader is a square, its vertical size seams to match the horizontal. How do I get it to just conform to the height of the TextFields.
GeometryReader { geometry in HStack(spacing: 20) {
TextField("Country...", text: $country)
.textFieldStyle(TextFieldDarkFull())
.frame(
width: geometry.size.width * 0.25
)
TextField("Phone...", text: $phone)
.textFieldStyle(TextFieldDarkFull())
.frame(
width: geometry.size.width * 0.75
)
}
}
.modifier(HorizontalPadding24())
remove second TextField frame limitation (ie. modifier width: geometry.size.width * 0.75). So you fix first text field and let second one consume all remaining space dynamically.
it depends of your entire layout but you can try to fix vertical size of block, like
GeometryReader { geometry in HStack(spacing: 20) {
// content here
}
.fixedSize(horizontal: false, vertical: true) // << here !!

Do I get an infinite loop when setting a ScrollView with a Geometry reader up?

I'm trying to figure out the basics of ScrollViews in SwiftUI.
I figured if I created a Text with a frame of the width of the screen and .infinite height, which I understood to mean "as large as the available space, e.g. safe area", and dropped it into a ScrollView with another Text companion, I'd get a screen-sized Text that could scroll horizontally to the companion Text.
struct ContentView: View {
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
GeometryReader { geometry in
VStack {
Text("crash me")
}
.frame(width: geometry.size.width,
height: .infinity,
alignment: .topLeading)
}
Text("crash me")
}
}
}
If I run this, it just crashes. What's so stupid about it?
Instead of:
.frame(height: .infinity)
You should use:
.frame(maxHeight: .infinity)
Setting the exact height to .infinity is not possible, but maxHeight means that the view will stretch its height to the maximum value possible. This would be the size of the screen, or any other limiting factor set by the parent.

How to have text in shapes in SwiftUI?

I want to add text (eg. Hi) in a shape (eg. Square) in SwiftUI and make them act as a single object.
It looks like there's no direct way to add text in shape in SwiftUI.
Here is what I consider to be a more comprehensive answer. This will work as of Xcode 11.5:
Text(question)
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(.center)
.padding()
.frame(width: 300, height: 200)
.background(Rectangle().fill(Color.white).shadow(radius: 3))
Notes:
fixedSize() will let the text wrap (since .lineLimit(nil) no longer is working). You can omit it if you simply want one line of text with ellipsis
multilineTextAlignment() allows you to center or align the text in any way
padding() gives the text more space to breathe within the Rectangle()
frame() sets the width and height of the Text() and hence, the Rectangle(), since it is the background of the Text()
background() sets the shape of the Text()'s background. I have added a fill color and a drop shadow here as well
The end result of this example is the text looks to appear within a cue card like shape!
Here is, IMO, most simple approach:
Generic schema
Text(_any_of_text_)
.background(_any_of_Shape)
eg:
Text("Hello, World!")
.background(Rectangle().stroke())
Text("Hello, World!")
.background(RoundedRectangle(cornerRadius: 4).stroke())
Using Swift built-in shapes such as Capsule(), RoundedRectangle() and etc. Then, you can apply .overlay to the shape. The overlay take in any view such as text.
Example:
var body: some View {
Capsule()
.fill(Color.blue)
.overlay(
Text("Hello World")
)
}
Outcome:
Text("Hi")
.frame(width: 40, height: 40, alignment: .center)
.background(Color.black)
.clipShape(Rectangle())
Create a new SwiftUI View and make use of a Z-Stack to create your goal.
struct YourCustomObject: View {
var body: some View {
ZStack {
Rectangle()
.fill(Color.secondary)
.frame(width: 200, height: 200)
Text("Your desired text")
.foregroundColor(.white)
}
}
}

SwiftUI: Images in a List are no longer center after adding a .frame maxHeight

I'm displaying a List of images, which works fine. They are all centered in the list, but when I add a maxHeight the images move to leading instead of center, so I set the alignment to .center, but that doesn't seem to do anything.
NavigationView {
List(words, id: \.self) { word in
NavigationLink(destination: testView(word: word)) {
Image(word.imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame( maxHeight: 200, alignment: .center )
}
}
}
Has anyone else had this problem and know how to solve it?
Thank you
This is the feedback I received from Apple:
Engineering has provided the following information regarding this
issue:
You need the frame to have an infinite width. This is a layout bug.
Please try using a frame with infinite width.
Setting the maxWidth to .infinity did provide a work around for the bug.
For example:
.frame(maxWidth: .infinity, maxHeight: 250)