How to make custom TextField in swiftUI - swiftui

How can I make a custom text field to look like this TextField because i am confused as to what modifiers i need to add to the standard textfield

You can use Divider, .overlay and .textFieldStyle(.plain)
#State private var age: String = ""
var body: some View {
VStack(alignment: .center) {
Text("Hey John, how old are you?")
.foregroundColor(.black)
.font(.system(size: 24, weight: .heavy))
VStack(alignment: .center) {
TextField("Age", text: $age)
.keyboardType(.numberPad)
.textFieldStyle(.plain)
.foregroundColor(.black)
.font(.system(size: 48, weight: .heavy))
.multilineTextAlignment(.center)
.accentColor(.black)
.padding(EdgeInsets(top: 0, leading: 60, bottom: 0, trailing: 60))
.overlay(Divider(), alignment: .bottom)
}
.padding(EdgeInsets(top: 0, leading: 50, bottom: 0, trailing: 50))
}
}

Related

SWIFTUI : Wide space appear on top as switch between tabs

Basically, I am working on a project in which there is a navigation process, therefore, I have to implement navigationview with tabview. As app loads, initial screen appear(homeview) normal, but an issue arises as soon I switch between tab option, wide space appears. So can anyone guide me in it? I am adding code with this query.
Even I have tried to add navigationView on individual tabitem and on it wide space issue gets resolve but new issue appear that tabbar doesnot hides on navigationlink even i have implemented "uitabbar.appearance.ishidden = true" on respective view
'''
import SwiftUI
struct TabBarView: View {
#State private var selection = 0
var body: some View {
NavigationView{
TabView(selection: $selection) {
HomeView()
.tabItem {
Image("tab_icon1")
.resizable()
.frame(width: 10, height: 10, alignment: .center)
}
.tag(0)
// Text("Search Tab")
SettingView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon2")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(1)
//tab_new
// Text("New Tab")
ActivityListView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_new")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(2)
HomeView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon3")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.tag(3)
Text("Profile Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image("tab_icon4")
.resizable()
.frame(width: 50, height: 50, alignment: .center)
}
.tag(4)
}
.edgesIgnoringSafeArea(.top)
.accentColor(Color("Pink"))
.onAppear() {
UITabBar.appearance().barTintColor = UIColor(named: "DarkGray")
UITabBar.appearance().backgroundColor = UIColor(named: "DarkGray")
}
//
}
}
}
'''

UINavigation Breaks on landscape mode in SwiftUI

Good afternoon community,
I have a problem with my app, I am trying to make it look good in both situations, so when I change orientation my app returns to the main screen, it does not stay on the second screen, will someone have a solution to this problem?
I don't know if my view breaks or cannot cover the space that I have determined, I leave my code below.
import SwiftUI
struct LoginView: View {
#Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
init() {
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: UIBarMetrics.default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().isTranslucent = true
UINavigationBar.appearance().tintColor = .clear
UINavigationBar.appearance().backgroundColor = .clear
}
var backButton : some View {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image("Backarrow")
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
Text(" Back")
.foregroundColor(.yellow)
}
}
}
var topImage:some View{
Image("header2")
.resizable()
.overlay( ImageOverlay() , alignment: .center)
.background(Color.black)
}
var usernameTextField:some View{
HStack{
TextField("", text: $LoginViewM.username)
.placeholder(Text("Numero de telefono,email o usuario").padding().foregroundColor(.white), show: LoginViewM.password.isEmpty)
.background(Color.black)
Image("menuCloseSmall")
.padding(.init(top: 0, leading: 0, bottom: 0, trailing: 14))
}
.lineLimit(1)
.foregroundColor(.white)
.minimumScaleFactor(0.5)
.font(.custom("Montserrat-Regular", fixedSize: 16.4))
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.gray, lineWidth: 3))
.clipShape(RoundedRectangle(cornerRadius: 4))
}
var errorUsernameLabel:some View{
VStack{
Text(" Hey you, no user found. Make sure you’ve provided the ")
.lineLimit(1)
Text("correct information.")
}
.multilineTextAlignment(.leading)
.foregroundColor(.redBlueParrot)
.minimumScaleFactor(0.5)
.font(.custom("Montserrat-Regular", size: 12.1))
}
var passwordTextField:some View{
HStack{
TextField("Contraseña", text: $LoginViewM.password)
.font(.custom("Montserrat-Regular", fixedSize: 16.4))
.padding(.bottom)
.foregroundColor(.white)
.placeholder(Text("Contraseña").padding().foregroundColor(.white), show: LoginViewM.username.isEmpty)
.lineLimit(1)
.minimumScaleFactor(0.5)
.background(Color.black)
Image("editShow")
.padding(.init(top: 0, leading: 0, bottom: 0, trailing: 14))
}
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.gray, lineWidth: 3))
.clipShape(RoundedRectangle(cornerRadius: 4))
}
var errorPasswordLabel:some View{
VStack{
Text(" Incorrect password for \(LoginViewM.password). Please try again.")
}
.lineLimit(1)
.minimumScaleFactor(0.5)
.foregroundColor(.redBlueParrot)
.font(.custom("Montserrat-Regular", size: 12.1))
}
var buttonLogin:some View{
NavigationLink(
destination: Text("Hola"),
label: {
Text("Iniciar sesion")
}) .font(.custom("Montserrat-Medium", size: 16))
.foregroundColor(Color.ligthGray)
.frame(minWidth: 0, idealWidth: 174, maxWidth: 174, minHeight: 0, idealHeight: 48, maxHeight: 48, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 18)
.stroke(Color.gray, lineWidth: 1.5))
}
var textInBottom:some View{
HStack(spacing:5){
Text("Olvidaste tu")
.foregroundColor(.white)
.font(.custom("Montserrat-Regular", size: 16))
Button("contraseña"){
}
.foregroundColor(.yellow)
.font(.custom("Montserrat-Regular", size: 16))
Text("o")
.foregroundColor(.white)
.font(.custom("Montserrat-Regular", size: 16))
Button("usuario"){
}
.foregroundColor(.yellow)
.font(.custom("Montserrat-Regular", size: 16))
}
}
#ObservedObject var LoginViewM = LoginViewModel()
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack(spacing:2){
topImage
.frame(width: geometry.size.width, height: geometry.size.height * 0.39)
VStack(spacing:17){
usernameTextField
.frame(width: geometry.size.width*0.90, height: geometry.size.height*0.05)
errorUsernameLabel
.frame(width: geometry.size.width*0.90,height: geometry.size.height*0.06, alignment: .center)
passwordTextField
.frame(width: geometry.size.width*0.90, height: geometry.size.height*0.05)
errorPasswordLabel
.frame(height: geometry.size.height*0.06, alignment: .center)
}.frame( height: geometry.size.height * 0.40)
VStack{
buttonLogin
}.frame(height: geometry.size.height * 0.10, alignment: .center)
Spacer()
textInBottom
.frame(height: geometry.size.height * 0.05, alignment: .center)
Spacer()
}
.ignoresSafeArea(.all)
.background(Color.black)
}
.navigationBarItems(leading: backButton)
.navigationBarBackButtonHidden(true)
.background(Color.black)
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
struct LoginView_Previews: PreviewProvider {
static var previews: some View {
LoginView()
}
}

Variable Rectangle() dimension based on cell size to draw a timeline

I am trying to build a List that I want to look like a timeline.
Each cell will represent a milestone.
Down the left hand side of the table, I want the cells to be 'connected', by a line (the timeline).
I have tried various things to get it to display as I want but I have settled with basic geometric shapes , i.e Circle() and Rectangle().
This is sample code to highlight the problem:
import SwiftUI
struct ContentView: View {
var body: some View {
let roles: [String] = ["CEO", "CFO", "Managing Director and Chairman of the supervisory board", "Systems Analyst", "Supply Chain Expert"]
NavigationView{
VStack{
List {
ForEach(0..<5) { toto in
NavigationLink(
destination: dummyView()
) {
HStack(alignment: .top, spacing: 0) {
VStack(alignment: .center, spacing: 0){
Rectangle()
.frame(width: 1, height: 30, alignment: .center)
Circle()
.frame(width: 10, height: 10)
Rectangle()
.frame(width: 1, height: 20, alignment: .center)
Circle()
.frame(width: 30, height: 30)
.overlay(
Image(systemName: "gear")
.foregroundColor(.gray)
.font(.system(size: 30, weight: .light , design: .rounded))
.frame(width: 30, height: 30)
)
//THIS IS THE RECTANGLE OBJECT FOR WHICH I WANT THE HEIGHT TO BE VARIABLE
Rectangle()
.frame(width: 1, height: 40, alignment: .center)
.foregroundColor(.green)
}
.frame(width: 32, height: 80, alignment: .center)
.foregroundColor(.green)
VStack(alignment: .leading, spacing: 0, content: {
Text("Dummy operation text that will be in the top of the cell")
.font(.subheadline)
.multilineTextAlignment(.leading)
.lineLimit(1)
Label {
Text("March 6, 2021")
.font(.caption2)
} icon: {
Image(systemName: "calendar.badge.clock")
}
HStack{
HStack{
Image(systemName: "flag.fill")
Text("In Progress")
.font(.system(size: 12))
}
.padding(.horizontal, 4)
.padding(.vertical, 3)
.foregroundColor(.blue)
.background(Color.white)
.cornerRadius(5, antialiased: true)
HStack{
Image(systemName: "person.fill")
Text(roles[toto])
.font(.system(size: 12))
}
.padding(.horizontal, 4)
.padding(.vertical, 3)
.foregroundColor(.green)
.background(Color.white)
.cornerRadius(5, antialiased: true)
HStack{
Image(systemName: "deskclock")
Text("in 2 Months")
.font(.system(size: 12))
}
.padding(.horizontal, 4)
.padding(.vertical, 3)
.foregroundColor(.red
)
.background(
Color.white
)
.cornerRadius(5, antialiased: true)
}
})
}.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct dummyView: View {
var body: some View {
Text("Hello, World!")
}
}
struct dummyView_Previews: PreviewProvider {
static var previews: some View {
dummyView()
}
}
but as you can see in the enclosed picture, there are unwanted gaps
So other content in the cell is making the height of the entire cell 'unpredictable' and break the line.
Is there a way to determine the height of the cell and extend the dimensions of the Rectangle, so that it extends to the full height of the cell?
Is there a better approach you recommend for trying to build such a timeline ?
PS: I have tried playing around with .frame and .infinity but that does work.
Many thanks.
Why not just draw the line based on the size of the row. See Creating custom paths with SwiftUI. Remember, everything is a view.
First, you need to decompose what you are doing into subviews. You have too many moving parts in one view to get it correct. Also, I would avoid setting specific padding amounts as that will mess you up when you change devices. You want a simple, smart view that is generic enough to handle different devices.
I would have a row view that has a geometry reader so it knows its own height. You could then draw the line so that it spanned the full height of the row, regardless of the height. Something along the lines of this:
struct ListRow: View {
var body: some View {
GeometryReader { geometry in
ZStack {
HStack {
Spacer()
Text("Hello, World!")
Spacer()
}
VerticalLine(geometry: geometry)
}
}
}
}
and
struct VerticalLine: View {
let geometry: GeometryProxy
var body: some View {
Path { path in
path.move(to: CGPoint(x: 20, y: -30))
path.addLine(to: CGPoint(x: 20, y: geometry.size.height+30))
}
.stroke(Color.green, lineWidth: 4)
}
}

Implementing Box-Shadow in SwiftUI

I'm trying to implement the following css code in SwiftUI
background: #FFFFFF;
box-shadow: 0px 10px 20px rgba(223, 227, 240, 0.2);
border-radius: 27.5px;
It should look like this (barely visible shadow below the button):
Here's the code i'm currently experimenting with:
import SwiftUI
struct RegisterView: View {
var body: some View {
VStack(spacing: 0) {
HStack(alignment: .top) {
Text("Register")
.font(.custom("NotoSans-Regular", size: 24))
.fontWeight(.bold)
.foregroundColor(Color.tertiaryTitleColor)
}
.frame(width: 299, height: 39)
.padding(.top, 78)
HStack {
BroviderButton(imageName: "googleLogo")
BroviderButton(imageName: "facebookLogo")
}
.padding(.top, 47)
Spacer()
}
.frame(maxHeight: .infinity)
.frame(maxWidth: .infinity)
.background(Color.loginBackgroundColor)
.ignoresSafeArea()
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView()
}
}
struct BroviderButton: View {
var imageName: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.stroke(Color.dropShadowColor,lineWidth: 1)
.frame(width: 133, height: 56, alignment: .center)
.shadow(color: .black, radius: 2, x: 1, y: 2)
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: .center)
}
.frame(width: 133, height: 56, alignment: .center)
.foregroundColor(.blue)
.background(Color.loginButtonBackgroundColor)
.cornerRadius(27.5)
.opacity(1)
}
}
}
And here's how it looks like atm:
I don't understand how to translate x:10 & y:20 to SwiftUI code and also can't find the way to blur the shadow (20%). Any ideas are welcome.
Also can't figure out why that RoundedRectangle stays visible after i put VStack on top of it.. I was thinking it will hide everything but the shadow below the button.
As far as I see there are two issues here to be fixed (although of course I don't have your colors and images):
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.fill(Color.dropShadowColor) // << here fill, not stroke !!
.frame(width: 133, height: 56, alignment: .center)
.shadow(color: .black, radius: 2, x: 0, y: 2) // << no offset by x
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: .center)
}
.frame(width: 133, height: 56, alignment: .center)
.foregroundColor(.blue)
.background(Color.loginButtonBackgroundColor) // << should be opaque color !!
.cornerRadius(27.5)
.opacity(1)
}

prevent views from expanding out of screen width

I have this view
import SwiftUI
struct DoctorCard: View {
let data: Doctor
var body: some View {
HStack(alignment: .top, spacing: 8) {
Image(data.image)
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(35)
.frame(width: 86, height: 86, alignment: .center)
.padding(.trailing, 5)
VStack(alignment: .leading, spacing: 4) {
Text(data.name.capitalized)
.foregroundColor(Colors.darkBlue)
.font(.system(size: 16, weight: .bold))
.fixedSize(horizontal: true, vertical: false)
.multilineTextAlignment(.leading)
Text(data.specialist)
.foregroundColor(Colors.gray)
.font(.system(size: 13, weight: .regular))
.fixedSize(horizontal: true, vertical: false)
.multilineTextAlignment(.leading)
Text(data.work)
.foregroundColor(Colors.gray)
.font(.system(size: 13, weight: .regular))
.fixedSize(horizontal: true, vertical: false)
.multilineTextAlignment(.leading)
HStack {
Image("location")
Text(data.location)
.foregroundColor(Colors.gray)
.font(.system(size: 13, weight: .regular))
.fixedSize(horizontal: true, vertical: false)
.multilineTextAlignment(.leading)
}
}.frame(maxWidth: .infinity)
// Spacer()
}.frame(maxWidth: screenSize.width - 30)
.padding()
.background(Color.white)
.cornerRadius(12)
}
}
struct DoctorCard_Previews: PreviewProvider {
static var previews: some View {
DoctorCard(data: Doctor(id: UUID().uuidString,
name: "Dr. Basma Saber",
specialist: "Dentist | General Dentistry | General Dentistry Dentistry",
work: "Works in West Bay Medicare",
location: "Al Dafna, Westbay",
image: "avatar",
review: 4))
}
}
How to prevent views from going out of screen? what am I missing?
The problem is your Dentist-line is too long and your code handles it the wrong way.
Do it like this:
Text("Dentist | General Dentistry | General Dentistry Dentistry")
.fixedSize(horizontal: false, vertical: true) // <--- like this
.lineLimit(2)
.foregroundColor(Color.gray)
.font(.system(size: 13, weight: .regular))
// .fixedSize(horizontal: true, vertical: false)
.multilineTextAlignment(.leading)