Why are Views misaligned? - swiftui

Any idea why the Text and NavigationLink views aren’t aligned to the left?
struct SettingsView: View {
var body: some View {
NavigationView {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
ScrollView {
VStack {
AccountActionsView()
}
.navigationBarTitle(Text("Settings"), displayMode: .inline)
}
}
}
}
}
struct AccountActionsView: View {
var body: some View {
ZStack {
CardView()
.foregroundColor(.black)
VStack(alignment: .leading, spacing: 8) {
Text("Account actions")
.font(.custom("ArialRoundedMTBold", size: 16))
.padding(.bottom)
NavigationLink("Account control") {
Form {
Button("Log out") {
}
Button("Delete account") {
}.foregroundColor(.red)
}
.font(.custom("ArialRoundedMTBold", size: 14))
.navigationBarTitle(Text("Account control"), displayMode: .inline)
}
NavigationLink("Blocked users list") {
}
}
.font(.custom("ArialRoundedMTBold", size: 14))
}
}
}

Related

Color behind the time on iOS

This is my code:
struct Account: View {
var body: some View {
VStack {
ScrollView {
HStack {
Text("Account")
.font(.largeTitle)
.fontWeight(.bold)
Spacer(minLength: 0)
}
.padding()
.background(Color.indigo)
VStack {
Text("Doe, John Jack")
.font(.title)
Divider()
.foregroundColor(Color.indigo)
HStack {
Text("")
}
}
Spacer(minLength: 0)
VStack {
Button(action: {
}) {
Text("Log Out")
.foregroundColor(.red)
.fontWeight(.bold)
}
}
}
}
}
}
If you run the code above, you will see that the indigo doesn't go behind the time and battery precentage. How can I make it do that?
Try like this:
struct Account: View {
var body: some View {
VStack {
ScrollView {
HStack {
Text("Account")
.font(.largeTitle)
.fontWeight(.bold)
Spacer(minLength: 0)
}
.padding()
.background(Color.indigo)
VStack {
Text("Doe, John Jack")
.font(.title)
Divider()
.foregroundColor(Color.indigo)
HStack {
Text("")
}
}
Spacer(minLength: 0)
VStack {
Button(action: {
}) {
Text("Log Out")
.foregroundColor(.red)
.fontWeight(.bold)
}
}
}.padding(.top, 66)
}
.background(Color.indigo)
.edgesIgnoringSafeArea(.all)
}
}
You would also have to add some top padding to the ScrollView since ignoring safe area is going to push all your views to the margins
You should ignore the top safe area for this:
.ignoresSafeArea(.container, edges: .top)
Full working example
struct ContentView: View {
var body: some View {
Color
.indigo
.ignoresSafeArea(.container, edges: .top)
}
}

SwiftUI - WatchOS - NavigationView - Layout issues

I am writing a simple watchOS app using SwiftUI but I am having issues to proper layout it.
This is the code:
struct ContentView: View {
var body: some View {
VStack(spacing: 0) {
HeaderView()
NavigationView {
ScrollView {
NavigationLink(destination: View1()) {
Text("View 1")
}
NavigationLink(destination: View2()) {
Text("View 2")
}
NavigationLink(destination: View2()) {
Text("View 3")
}
NavigationLink(destination: View2()) {
Text("View 4")
}
}
}
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct HeaderView: View {
var body: some View {
VStack() {
Text("Header")
}
.frame(maxWidth: .infinity)
.background(Color.red)
}
}
struct View2: View {
var body: some View {
VStack {
Text("View 2 Content")
}
.navigationTitle("View 2")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button("+") {
}
}
}
}
}
Issues:
I cannot rid of this unused space
No matter what the "+" button shows up below the toolbar. I would like to have it in the shown position

ScrollViewReader is not working and building is pretty slow

I couldn't figure out why it is not working my ScrollViewReader below my code. Please help me figure out the issue. I want to pass my zolyric.number into scrollToIndex and that scrollToIndex will set the number that I want to scroll in my HymnLyrics(). Also, although I couldn't find the error, the building is pretty slow.
Here ZolaiTitles() is the same list just sorting the song titles algebraically and HymnLyrics() is the one to display in the canvas.
struct ZolaiTitles: View {
#AppStorage("scrollToIndex") var scrollToIndex: Int?
#EnvironmentObject var tappingSwitches: TapToggle
let zoLyrics: [Lyric] = LyricList.hymnLa.sorted { lhs, rhs in
return lhs.zoTitle < rhs.zoTitle
}
var body: some View {
ScrollView {
ForEach(zoLyrics, id: \.id) { zoLyric in
VStack {
Button(action: {
//if let lyricNum = String(zoLyric) {
scrollToIndex = zoLyric.number // zolyric.number is already an interger.
//}
self.tappingSwitches.isHymnTapped.toggle()
}, label: {
HStack {
Text(zoLyric.zoTitle)
.foregroundColor(Color("bTextColor"))
.lineLimit(1)
.minimumScaleFactor(0.5)
Spacer()
Text("\(zoLyric.number)")
.foregroundColor(Color("bTextColor"))
}
})
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding([.leading, .bottom, .trailing])
}
}
}
}
struct HymnLyrics: View {
#AppStorage("scrollToIndex") var scrollToIndex: Int = 1
var lyrics: [Lyric] = LyricList.hymnLa
#AppStorage("fontSizeIndex") var fontSizeIndex = Int("Medium") ?? 18
#AppStorage("fontIndex") var fontIndex: String = ""
#AppStorage("showHVNumbers") var showHVNumbers: Bool = true
var body: some View {
ScrollViewReader { proxy in
List(lyrics, id: \.id) { lyric in
VStack(alignment: .center, spacing: 0) {
Text("\(lyric.number)")
.padding()
.multilineTextAlignment(/*#START_MENU_TOKEN#*/.leading/*#END_MENU_TOKEN#*/)
.id(lyric.number)
VStack {
VStack {
Text(lyric.zoTitle)
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.primary)
.autocapitalization(.allCharacters)
Text(lyric.engTitle)
.font(.title3)
.fontWeight(.medium)
.foregroundColor(.secondary)
.italic()
}
// Don't use Padding here!
}
.multilineTextAlignment(.center)
HStack {
Text(lyric.key)
.italic()
Spacer()
Text(lyric.musicStyle)
}
.foregroundColor(.blue)
.padding(.vertical)
}
//.id(lyric.number)
}
.onChange(of: scrollToIndex, perform: { value in
proxy.scrollTo(value, anchor: .top)
})
}
}
}

SwiftUI - Button Action to Alert and take action

I am trying to send alert based on a condition, but the Navigation link is executing regardless of the condition. I was hoping for an intercept.
Goal:
If condition is not me then do not launch new view
New View is launching and then alert.
I am sure my code is incorrect, but I am unsure how I should achieve this
Thanks in advance.
var body: some View {
NavigationView {
VStack {
Button(action: {}) {
//NavigationLink(destination: secondView()) {
NavigationLink(destination: checkState()) {
Text("Add to Cart")
}.padding()
.font(.system(size: 14))
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(6)
}
}
}.padding()
} // End of the GetOrder Struct
struct GetdOrderView_Previews: PreviewProvider {
static var previews: some View {
GetdOrderView()
}
}
}
struct checkState: View {
#ObservedObject var calcCheck = MealOrder()
#State var showingAlert = false
#State var myToggle = false
var body: some View {
NavigationView {
VStack {
Button(action: {
//Enter Action here
if self.myToggle == true {
self.showingAlert = true
} else {
self.showingAlert = true
}
}) {
Text("This is a test")
}.padding()
.font(.system(size: 14))
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(6)
//Insert Alerts
.alert(isPresented: $showingAlert) {
if self.myToggle {
return Alert(title: Text("Showing Message"), message: Text("Cart is valid"), dismissButton: .default(Text("OK")))
} else {
return Alert(title: Text("Showing Alert"), message: Text("Cart Empty"), dismissButton: .default(Text("Cancel")))
}
}
}
}
}
}
struct secondView: View {
var body: some View {
VStack {
Text("This is the second test")
}
}
}
Try the following approach
#State var activateLink = false
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: checkState(), isActive: $activateLink) {
EmptyView()
}
Button(action: {
if _YOUR_CONDITION_HERE_ {
self.activateLink = true
}
}) {
Text("Add to Cart")
.padding()
.font(.system(size: 14))
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(6)
}
}
.onAppear { self.activateLink = false }
}.padding()
}// End of the GetOrder Struct

SwiftUI - centre content on a List

How can I make this arrow on the centre of the list?
struct ProductsList : View {
var body: some View {
VStack {
List {
Image(systemName: "shift")
}
}
}
}
You may just wanna use some Spacers.
struct ProductList : View {
var body: some View {
VStack {
List {
HStack {
Spacer()
Image(systemName: "shift")
Spacer()
}
}
}
}
}
I would suggest to use ViewModifier:
struct CenterModifier: ViewModifier {
func body(content: Content) -> some View {
HStack {
Spacer()
content
Spacer()
}
}
}
so that in your list, if you have more different type of UI elements its more convenient way to do so:
struct ExampleList: View {
var body: some View {
List {
Image(systemName: "shift").modifier(CenterModifier())
SomeOtherView().modifier(CenterModifier())
}
}
}
Try this:
var body: some View {
List {
GeometryReader { geometry in
VStack(alignment: .center) {
Image(systemName: "shift")
}.frame(width: geometry.size.width)
}
}
}