I have a small HStack with Text and a Button. This is limited with maxWidth: 200
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
Text("Some Text")
.frame(maxWidth: .infinity)
Button(action: {}, label: {
Text("A Very much to long button Text with more Text")
.truncationMode(.middle)
})
}.frame(maxWidth: 200)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
This ends up scaling the button even beyond the borders of the HStack.
I do not want to hardcode a width with .frame(maxWidth: 50 on the Buttons Label Text.
It should just take as much space as possible, after that truncating the text (.truncationMode)
How can this be done without GeometryReader so that the result looks like:
Update
As suggested, XCode is checked latest 13.2 on macOS 11.6
Seems to be related to known issues with macOS.
Only solution is, to create a custom ButtonStyle and apply the necessary restrictions there:
struct MacOSFixedButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.truncationMode(.middle)
.lineLimit(1)
}
}
extension View {
func fixedMacOSButton(
) -> some View {
self.buttonStyle(
MacOSFixedButtonStyle()
)
}
}
Applied via:
Button("to long to read it and to put it in a view", action: {})
.fixedMacOSButton()
Related
Prior to iOS 16, screen background in a NavigationView used to work very reliably in SwiftUI.
In iOS 16, there is a hollow space (without background color) when navigating back and forth with on-screen-keyboard:
Repro code:
import SwiftUI
struct ContentView: View {
#State private var text: String = ""
var body: some View {
NavigationView {
VStack {
TextField("Edit field", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
NavigationLink(destination: Text("Naviagtion target")) {
HStack {
Image(systemName: "link")
Text("Navigation Link")
}
}
.padding(30)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.gray)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Any ideas how to fix this?
It does look and feel like a bug, where the safe area that’s adjusted when the keyboard appears doesn’t re-adjust when you navigate back and the keyboard’s not there.
One way round the bug is to adjust the background’s idea of what the safe area is, by telling it to always reclaim the keyboard space:
.background(
Color.gray
.ignoresSafeArea(.keyboard)
)
Because you’re only adjusting the safe area for the background, the rest of your view should continue to behave as before. That means that it’s still elevated to accommodate the (missing) keyboard’s space requirement, but it’s less obvious.
I am trying to learn swiftui and faced with "markup" problem. I need to build a UI with textfield in a toolbar (like address line in Safari):
I've tried to do it like this:
import SwiftUI
struct ContentView: View {
#State var searchText: String = ""
var body: some View {
NotesListView(notesRepo: InMemoryNotesStubRepository())
.frame(minWidth: 500, minHeight: 300)
.toolbar {
ToolbarItem(placement: .primaryAction){
TextField("Search", text: $searchText)
.frame(minWidth: 300)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
And I've got something weird:
Can anyone help me how to add a textfield to a toolbar like in is in Safari (address line)?
It is possible to use style for TextField, like
ToolbarItem(placement: .primaryAction){
TextField("Search", text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minWidth: 300)
}
of even custom style with with look & feel you need, see next for example https://stackoverflow.com/a/63976054/12299030
I have a problem related on my List view. The question is simple: how can I get rid of that wierd gray rectangle showing on top of the TabBar? I didn't code that, I just implemented a controller with a List and NavigationBar and then it showed that thing.
For more clear explanation I post the images:
ItemRow.swift code:
import SwiftUI
struct ItemRow: View {
static let colors: [String: Color] = ["D": .purple, "G": .orange, "N": .red, "S": .yellow, "V": .pink]
var item: MenuItem
var body: some View {
NavigationLink(destination: Text(item.name)) {
HStack {
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle().stroke(Color("IkeaBlu"), lineWidth: 2))
VStack(alignment: .leading){
Text(item.name)
.font(.headline)
Text("€ \(item.price)")
}.layoutPriority(1)
Spacer()
ForEach(item.restrictions, id: \.self) { restriction in
Text(restriction)
.font(.caption)
.fontWeight(.black)
.padding(5)
.background(Self.colors[restriction, default: .black])
.clipShape(Circle())
.foregroundColor(.white)
}
}
}
}
}
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}
thanks a lot for the help
Remove the marked part of hack from TabBar view and that glitch will go.
Tested with Xcode 11.4 / iOS 13.4
} .onAppear {
// UITabBar.appearance().isTranslucent = false // << this one !!
UITabBar.appearance().barTintColor = UIColor(named: "IkeaBlu")
}.accentColor(Color(.white))
I want to display a label in the centre of a view with a progress indicator to the right of the label. How can I do this in SwiftUI on macOS?
The code below aligns the HStack in the centre of the VStack but I want the text centered and the progress indicator aligned with the text's trailing edge. I guess I could replace the HStack with a ZStack but it's still not clear how one aligns two controls to each other or how one prevents the container from be centered by its container.
import SwiftUI
struct AlignmentTestView: View {
var body: some View {
VStack(alignment: .center, spacing: 4) {
HStack {
Text("Some text")
ActivityIndicator()
}
}.frame(width: 200, height: 200)
.background(Color.pink)
}
}
struct AlignmentTestView_Previews: PreviewProvider {
static var previews: some View {
AlignmentTestView()
}
}
Here is possible approach (tested replacing ActivityIndicator with just circle).
Used Xcode 11.4 / iOS 13.4 / macOS 10.15.4
var body: some View {
VStack {
HStack {
Text("Some text")
.alignmentGuide(.hAlignment) { $0.width / 2.0 }
ActivityIndicator()
}
}
.frame(width: 200, height: 200, alignment:
Alignment(horizontal: .hAlignment, vertical: VerticalAlignment.center))
.background(Color.pink)
}
extension HorizontalAlignment {
private enum HAlignment : AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[HorizontalAlignment.center]
}
}
static let hAlignment = HorizontalAlignment(HAlignment.self)
}
I want to have a full screen image in the background. I have implemented this:
struct LoginView: View {
var body: some View {
VStack {
Spacer();
Text("Hallo");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Text("Hallo2");
Spacer();
}.background(Image("Background LaunchScreen")
.resizable()
.aspectRatio(UIImage(named: "Background LaunchScreen")!.size, contentMode: .fill)
.clipped())
.edgesIgnoringSafeArea(.all)
}
}
When I remove the spacers, the image is no longer displayed in full screen mode.
Surely that can be solved differently?
And if I turn the iPhone in the simulator to the side, I have left and right white stripes.
How can I change this?
Here's a possible solution using GeometryReader and ZStack:
import SwiftUI
struct LoginView: View {
var body: some View {
GeometryReader { geometry in
ZStack {
Image("LaunchImage")
.resizable()
.aspectRatio(geometry.size, contentMode: .fill)
.edgesIgnoringSafeArea(.all)
VStack {
ForEach (1...10, id: \.self) { _ in
Text("Hallo")
.foregroundColor(Color.white)
}
}
}
}
}
}
#if DEBUG
struct LoginView_Previews: PreviewProvider {
static var previews: some View {
LoginView()
}
}
#endif
Results