Aligning image to navigationBarTitle in SwiftUI - swiftui

I'm trying to add a User Image (button) next to the .navigationBarTitle, but with the code bellow, the image appears on top of the title alignment. (picture attached). Many thanks for your help!
.navigationBarTitle(Text("Watch"))
.navigationBarItems(trailing:
Image("User")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 36, height: 36)
.clipShape(Circle())
)
Image should be bottom - aligned to the text

This code produces this view:
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("Chocolate")
Text("Vanilla")
Text("Strawberry")
}.navigationBarTitle(Text("Watch"))
.navigationBarItems(trailing:
Image(systemName: "person.circle")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 36, height: 36)
.clipShape(Circle())
.padding(.top, 90)
)
}
}
}
There is a default space for the Items and a default space for the Text. Imagine it like two HStacks in a VStack. Where the Title is in the lower HStack and the items are in the upper one. There is no "real" way on getting in the lower one.
I'd recommend to create an own NavigationBar for your purposes.

Thanks #Simon, the best option for what I was looking for is to Add the User Icon to the Title (not NavBar) and apply an Offset of y: -55. When scrolling up the icon disappears under the NavBar. The same effect on the Apple TV app (mobile).` VStack(alignment: .leading) {
HStack {
Text("Children")
.font(.title)
.fontWeight(.bold)
.padding(.leading, 24)
.padding(.top, 20)
Spacer ()
Image("User")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 36, height: 36)
.clipShape(Circle())
.offset(y: -55)
.padding(.trailing, 24)[final result][1]`

Related

SwiftUI - Sheet shows Data half way down the sheet

I am building a small APP where I wanna present a Sheet when a Button is pressed, it all works fine, but when the Sheet is presented the Data starts half way down the Screen rather than at the Top. I am using a ScrollView in the Sheet and above the ScrollView I have a Text and an Image which is Static.
I tried pretty much everything I could find and think of without any success. So now I am hoping someone out there can help me with this.
Here is what it looks like:
Here is the start of the code:
import SwiftUI
struct PopupView: View {
#State var painted = CGFloat(10)
#State var unpainted = CGFloat(1)
#State var sPainted = CGFloat(5)
#State var sUnpainted = CGFloat(6)
var body: some View {
Color.white
VStack(alignment: .leading, spacing: 0) {
HStack {
Text("T'IS IS STATIC HEADER TXT")
.tracking(2)
.foregroundColor(Color.euGray)
.fontWeight(.bold)
.font(.system(size: 12))
.padding(.leading, 100)
.padding(.trailing, 20)
Image("close")
.frame(width: 35, height: 35, alignment: .trailing)
}
}.frame(width: 400, alignment: .topLeading)
ScrollView(showsIndicators: false) {
VStack(alignment: .center) {
Image("qr")
.resizable()
.clipped()
.padding(.top)
.frame(width: 320, height: 320, alignment: .center)
.padding(.top, 5)
Text("JOHN APPLESEED")
.foregroundColor(Color.nameGray)
.fontWeight(.heavy)
.font(Font.custom("Source Sans Pro" ,size: 27))
.padding(.top, 10)
Text("01.01.1976")
.foregroundColor(.gray)
.fontWeight(.regular)
.font(.system(size: 13))
}.frame(width: 320)

Custom navigation bar's button doesn't work (SwiftUI)

I am currently learning SwiftUI and I followed this video to create a custom NavigationBar.
Learn how to create a custom navigation bar with a logo in SwiftUI framework and Xcode - Part 2
The buttons doesn't work when I click on it unless I don't use padding() and ignoreSafeArea(), but without using it, the navigationBar would appear on middle of the page. (I also tried use Spacer() but it didn't work)
Is there anyway to fix this issue?
Code for HomePage()
VStack{
NavigationBarView()
.padding(.horizontal, 15)
.padding(.bottom)
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
.shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 5)
.ignoresSafeArea(.all, edges: .top)
Code for NavigationBarView()
HStack{
NavigationLink(
destination: PersonalMenuPage()
,label: {
ZStack {
Image("Profile")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.padding(.horizontal, 10)
Circle()
.fill(Color.red)
.frame(width:14, height: 14, alignment: .center)
.offset(x: 13, y: -10)
}
}
)
}//: hStack
Here is sample output
Sample output

How to prevent Text from expanding the width of a VStack

I have a VStack that contains an Image and a Text. I am setting the width (and height) of the Image to be half of the screen's width:
struct PopularNow: View {
let item = popular[0]
var body: some View {
VStack(spacing: 5) {
Image(item.image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: getRect().width/2, height: getRect().width/2)
Text(item.description)
.font(.caption)
.fontWeight(.bold)
.lineLimit(0)
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(15)
}
func getRect() -> CGRect {
return UIScreen.main.bounds
}
}
The problem is that the Text pushes and causes the VStack to expand instead of respecting the Image's width. How can I tell the Text to not grow horizontally more than the Image width and to grow "vertically" (i.e. add as many lines it needs)? I know that I can add the frame modifier to VStack itself, but it seems like a hack. I want to tell the Text to only take as much space width wise as VStack already has, not more.
This is what it looks like right now, as you can see the VStack is not half the screen's size, it's full screen size because the Text is expanding it.
Try to fix its size, like
VStack(spacing: 5) {
Image(item.image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: getRect().width/2, height: getRect().width/2)
Text(item.description)
.font(.caption)
.fontWeight(.bold)
.lineLimit(0)
}
.fixedSize() // << here !!
// .fixedSize(horizontal: true, vertical: false) // alternate
.padding()

swiftui edgesIgnoreSafeArea only showing on canvas and not working on actual device

Im using .edgesIgnoringSafeArea(.top) to ignore the safe area on the top. this seems to work, and show the image going over the safe area on the top as expected on the canvas. But when I run this on a iPhone 11 plus simulator or iPhone x device (i also tested on other devices on the simulator) it doesn't seem to ignore the edges.
I have tried excluding:
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
But I need the above so I can use a custom back button.
var body: some View {
VStack (alignment: .leading ) {
Image("user1")
.resizable()
.frame(width: (UIScreen.main.bounds.width), height: ((UIScreen.main.bounds.height) / 2) + 50)
ScrollView {
HStack {
Text("\(userData.username), 30")
.fontWeight(.semibold)
.font(.system(.largeTitle, design: .rounded))
.padding([.leading,.top])
Spacer()
Image(systemName: "paperplane")
.aspectRatio(contentMode: .fill)
.frame(width: 65, height: 65)
.background(Color("message-background"))
.foregroundColor(.white)
.cornerRadius(25)
.font(.system(size: 25))
.padding(.top)
}.padding(.trailing)
HStack {
Text("Singer, London")
.fontWeight(.light)
.padding([.leading])
Spacer()
}
HStack {
Text("all the bio info will go there all the bio info will go thereall the bio info will go thereall the bio info will go there all the bio info will go there.")
.fontWeight(.light)
.padding([.leading])
.padding(.top)
.frame(width: (UIScreen.main.bounds.width - 20))
Spacer()
}.padding(.bottom,50)
}
}.edgesIgnoringSafeArea(.top)
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}){
Image(systemName: "arrow.left")
.aspectRatio(contentMode: .fill)
.frame(width: 40, height: 40)
.background(Color("message-background"))
.foregroundColor(.white)
.cornerRadius(15)
.font(.system(size: 15))
.padding(.top,20)
})
}
Your code works for me on the simulator as expected. I just added the Text "This works" to demonstrate it:
So your problem must be somewhere outside the code which you presented in your question.

SwiftUI button image inset

Is there same thing as ImageEdgeInsets for SwiftUI. For example I have button 60x60. And want to make inset for image inside.
VStack(alignment: .leading, spacing: 0.0){
Section{
Button(action: {
if self.accountViewModel.signInContext == .quote{
self.presentationMode.wrappedValue.dismiss()
}else{
self.viewController?.dismiss(animated: true)
}
}){
Image("Close Icon").renderingMode(.template).padding(.vertical, 20).padding(.horizontal, 20).foregroundColor(.white).scaledToFit()
}
.frame(width: 60, height: 60)
Rectangle().line().padding(.horizontal, -30)
}
}
Yes, .padding is for that purpose, just needed to make image resizable. I suppose you need the following
Image("Close Icon")
.renderingMode(.template)
.resizable()
.aspectRatio(contentMode: .fit)
.padding(.vertical, 20).padding(.horizontal, 20)