MacOS swiftUI Custom ui TextField field with rounded edge - swift

I'm having trouble customizing a TextField field, I would like to try to have a border equal to that of the first image for both:
Border color
Edge thickness dimension
Type of edge rounding
Can anyone give me advice?
Result I would like to achieve:
Result I get:
HStack(alignment: .center) {
Spacer()
TextField("Git Repository URL", text: $repoUrlStr)
.textFieldStyle(PlainTextFieldStyle())
.lineLimit(1)
.frame(width: 300)
.onAppear {
let url = "https://github.com/name/name"
if isValid(url: url) == true {
print("ok", url)
}
}
Button {
if !repoUrlStr.isEmpty {
self.repoUrlStr = ""
}
} label: {
Image(systemName: "xmark.circle.fill")
.padding(.trailing, 2)
.font(.system(size: 12))
}
.buttonStyle(PlainButtonStyle())
.opacity(repoUrlStr.isEmpty ? 0 : 1)
Spacer()
}
.padding([.top, .bottom], 4)
.border(Color.gray, width: 2)
.cornerRadius(3)
.padding(.bottom, 15)

Try to use rounded rectangle in background (with needed parameters, like corner radius, color, etc) instead of border, like
.background(
RoundedRectangle(cornerRadius: 8)
.stroke(your_color_here)
)

Related

How to override the alignment of a VStack if all component don't have fixed frames?

I have an HStack, aligned top, with 3 components. I want the first Text to be pushed to the bottom, essentially overriding the HStack's alignment.
I want the Text to keep its intrinsic size and override its parent's alignment.
HStack(alignment: .top, spacing: 0) {
Text("BOTTOM")
.font(.system(size: 24))
.background {
Color.yellow
}
Spacer()
Text("TOP ")
.background {
Color.blue
}
Spacer()
Text("X")
.font(.system(size: 40))
.background {
Color.green
}
}
.background {
Color.red
}
I can wrap the Text in a VStack and add a Spacer before it but that will only work if
there is a fixed frame height on the Text OR
there is a fixed frame height on the HStack
If I don't have either and still add a Spacer, the Spacer stretches to take up the entire screen height.
Create two HStacks, the outermost aligned to the bottom, while an inner one wraps the second block, aligning everything to the top.
Here:
// Align the whole block to the bottom
HStack(alignment: .bottom, spacing: 0) {
Text("BOTTOM")
.font(.system(size: 24))
.background {
Color.yellow
}
// The sub-block is aligned to the top: create
// a new HStack
HStack(alignment: .top) {
Spacer()
Text("TOP ")
.background {
Color.blue
}
Spacer()
Text("X")
.font(.system(size: 40))
.background {
Color.green
}
}
}
.background {
Color.red
}

SwiftUI Centering Image between Views

I have an HStack that I am using as a tool bar. The HStack contains a button on the left, image in the middle, and then another HStack containing 2 buttons. Everything looks fine except for the image in the middle, it's slightly to the left. How can I get the image centered?
var toolbar: some View {
HStack(alignment: .center) {
Button {
UIImpactFeedbackGenerator(style: .light).impactOccurred()
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.tint(.black)
}
Spacer()
Image("nav_logo")
.resizable()
.frame(width: 30, height: 30)
Spacer()
optionsButton
}
.frame(height: 30)
}
var optionsButton: some View {
HStack {
Button {
UIPasteboard.general.string = viewModel.take.shareLinkString
self.buildBottomAlert(type: .linkCopied)
} label: {
Image("shareIcon")
}
.padding(.trailing, 10)
Button {
showingAlert = true
} label: {
Image("moreMenu")
}
}
The image in the middle is offset because the first button and optionsButton do not have the same width. But the SpacerĀ“s inside the containing Stack do have equal width.
To solve this you could wrap them in to a container that is big enough so both have the same width.
e.g.:
//GeometryReader to get the size of the container this is in
GeometryReader{proxy in
HStack(alignment: .center) {
//Hstack to wrap the button
HStack(){
Button {
UIImpactFeedbackGenerator(style: .light).impactOccurred()
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.tint(.black)
}
// Spacer to move the button to the left
Spacer()
}
// depending on the use case you would need to tweak this value
.frame(width: proxy.size.width / 4)
Spacer()
Image(systemName: "square.and.arrow.up.trianglebadge.exclamationmark")
.resizable()
.frame(width: 30, height: 30)
Spacer()
HStack(){
Spacer()
optionsButton
}
.frame(width: proxy.size.width / 4)
}
.frame(height: 30)
}

How to avoid Image size shrink when aligning

New to this framework i know i'm not good at aligning part of UI yet.
My aligning problem is my image get shrink the more padding it has so if possible can you go easy and point out my mistake here? i am practicing align my item to top left corner.
struct MasterLabMerge: View {
var body: some View {
ZStack {
Color.gray.ignoresSafeArea()
Image(systemName: "note")
.frame(width: 300, height: 300)
.padding(.leading, -300)
.padding(.top, -500)
}
}
}
You need to add .resizable() to enable an image to grow in size.
Also, you can align your item to the top left in better ways.
Option 1 (I personally think this is the best):
ZStack {
Color.gray.ignoresSafeArea()
VStack {
HStack {
Image(systemName: "note")
.resizable()
.frame(width: 100, height: 100)
.padding(.leading)
Spacer()
}
Spacer()
}
}
Option 2:
ZStack {
Color.gray.ignoresSafeArea()
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Image(systemName: "note")
.resizable()
.frame(width: 100, height: 100)
.padding(.top)
}
}

Align text to side of screen (SwiftUI)

Using Swiftui I'm creating a chat application. I'm trying to align the text so that it appears on the right side of the screen and then messages from the other user will appear on the left. I have tried using VStack and using leading and trailing alignment, I have also tried just aligning the text attribute. I have a text, and then two buttons. I would like the trash can button and pencil button to all evenly line up on the right side.
VStack (alignment: .trailing ) {
HStack {
Text(data.text)
.padding(.bottom, 4)
.padding(.top, 4)
.padding(.leading, 8)
.padding(.trailing, 8)
.foregroundColor(Color.white)
.background(Color(UIColor.systemBlue))
.cornerRadius(20)
Button(action: {
self.showingPopover = true
}) {
Image(systemName: "pencil")
}
Button(action: {
viewModel.deleteData(id: data.id)
}) {
Image(systemName: "trash")
}
}
}
It is enough to use frame alignment for text, depending to user it can be conditionally changed in place, like
Text(data.text)
.padding(.bottom, 4)
.padding(.top, 4)
.padding(.leading, 8)
.padding(.trailing, 8)
.foregroundColor(Color.white)
.background(Color(UIColor.systemBlue))
.cornerRadius(20)
.frame(maxWidth: .infinity, alignment: isMe ? .trailing : .leading) // << here !!
You just need to add a Spacer() in the beginning of the HStack:
VStack (alignment: .trailing ) {
HStack {
// This Spacer() will "push" the text to the right
Spacer()
Text(data.text)
.padding(.bottom, 4)
.padding(.top, 4)
.padding(.leading, 8)
.padding(.trailing, 8)
.foregroundColor(Color.white)
.background(Color(UIColor.systemBlue))
.cornerRadius(20)
Button(action: {
self.showingPopover = true
}) {
Image(systemName: "pencil")
}
Button(action: {
viewModel.deleteData(id: data.id)
}) {
Image(systemName: "trash")
}
}
}
Similarly, for the replies put a Spacer() at the end of the HStack, too push the text to the left.

List covers custom view in SwiftUI

I am currently having a issue with SwiftUI when I put "Grid" (Github URL) in to a list, it gets covered by the next cell. But when I expand the "Text" the cell becomes larger.
List(0 ..< colorArray.count) { i in
VStack(alignment: .leading, spacing: 8) {
Text("a")
.font(.body)
.multilineTextAlignment(.leading)
.padding(.horizontal, 10)
.lineLimit(nil)
Grid {
ForEach(self.colorArray[i], id: \.self) { color in
RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color(color))
.frame(width: 80.0, height:80.0)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color(UIColor.label),
lineWidth: 0.5)
)
}
}
.padding(.horizontal, 8)
.gridStyle(
AutoColumnsGridStyle(minItemWidth: 80, itemHeight: 80, hSpacing: 8, vSpacing: 8)
)
}
}
How can I make it that the "Grid" doesn't get covered up like in the picture below.
It's impossible to recreate this because your code is incomplete, but applying
.aspectRatio(contentMode: .fit)
either to Grid or the whole VStack should force the cell to have the right size.