SwiftUI how to make UI Responsiv - swift

UI on iPhone Pro Max here the UI is not in the right place
UI on iPhone Pro thats perfectly
Hello I am new to SwiftUI and have a question. I had to implement the UI with the Star and the Number Count. I did everything, but when I switch the phones my UI is miss placed depends on the iPhone I choose. How can I fix that ? I search in the Internet for Responsiveness in SwiftUI but it didn't really helped me. I thought also that SwiftUI does most of the Responsiveness because I know in UIKIT you have to declare the constraints by yourself. Thanks for helping me, the Code is below. I also have after the CustomerCardPoints an List which works perfectly but since I added the CustomerCardPoints there is a small space between the Views, if anybody has experience how can I fix that also? (Not Necessary)
var body: some View {
VStack(spacing: 0) {
shopModel.logo
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 200, maxHeight: 100)
.padding([.top, .leading, .trailing])
Text(shopModel.name)
.fontWeight(.bold)
.padding()
CustomerCardPoints()
}
struct CustomerCardPoints: View {
var body: some View {
VStack(){
ZStack() {
Image("Slice")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 180, maxHeight: 60)
.offset(x: 160, y: -127)
HStack(alignment: .firstTextBaseline) {
Text("22")
.font(.system(size: 19))
.fontWeight(.bold)
.foregroundColor(.white)
.offset(x: 237, y: -126)
Image("favoriten")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 110, height: 25)
.offset(x: 132, y: -120)
}
}
}
}
}

Related

SwiftUI Horizontal ScrollView onTapGesture is Off

I am experiencing some very odd behavior from a Horizontal ScrollView, it seems as if the clickable frame of the cells are offset. For example, if you click on left half of the first cell it will register the click for the first cell, but if you click the right half of the first cell it will register a click on the second cell. I'm not sure why this is happening.
I've included the code below, you can copy and paste this code into a playground to reproduce the issue. Any ideas here?
struct TestView: View {
var image: String
var body: some View {
ZStack {
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 104, height: 168)
.cornerRadius(8)
.clipped()
VStack {
Spacer()
Text("Testing")
.foregroundColor(Color.white)
.frame(alignment: .leading)
.padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
.shadow(radius: 5)
Text("1:40")
.foregroundColor(Color.white)
.frame(alignment: .leading)
.padding(EdgeInsets(top: 3, leading: 10, bottom: 10, trailing: 10))
.shadow(radius: 5)
}
.frame(width: 104, height: 168)
}
}
}
struct TestViewCollection: View {
var collection = ["tv", "faxmachine", "printer"]
var body: some View {
ScrollView {
HStack {
ForEach(collection, id: \.self) { image in
TestView(image: image)
.onTapGesture {
print(image)
}
}
}
}
}
}
PlaygroundPage.current.setLiveView(TestViewCollection())
The issue is that your images are not the same aspect ratio as the frame you have put them in, so they are overflowing the frame. The solution is pretty simple. Instead of using .clipped() which just clips what you can see, use .contentShape() which will will provide an area that the .tapGesture() will use as its tappable area. Like this:
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 104, height: 168)
.cornerRadius(8)
.contentShape(Rectangle())
the problem is:
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 104, height: 168)
.cornerRadius(8)
.clipped()
Change that .aspectRatio(contentMode: .fill). -> into .fit
if you just move .clipped() like this:
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fill)
.clipped()
.frame(width: 104, height: 168)
You are going to see:
That's why is happening.

In SwiftUI what is an easy way to align more than one view in ZStack

I have a view and I want to add two icons to it, at top right side and at bottom right side. I managed to do that:
I used two ZStacks:
ZStack(alignment: .bottomTrailing)
{
ZStack(alignment: .topTrailing)
{
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle()
.stroke(Color.gray, lineWidth: 2))
if item.isFavorite
{
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7)
}
}
if item.ordered
{
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7)
}
}
But I have a feeling that there should be a simpler way than nesting ZStacks inside. Besides looks like the small icons don't have their x-centers aligned. I can probably fix that by changing an offset but that would make the code even more clumsy.
Is there a simpler way?
Use only one Zstack and wrap the two icons in a VStack.
ZStack(alignment: .trailing) {
Circle()
.stroke(Color.gray, lineWidth: 2)
VStack {
Image(systemName: "star.fill")
Spacer()
Image(systemName: "checkmark.square.fill")
}
// Adjust the position of star and checkmark
.offset(x: -10)
}
.frame(width: 100, height: 100)
You can use the overlay modifier, like this:
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7),
alignment: .topTrailing)
.overlay(
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7),
alignment: .bottomTrailing)
.padding()
)
If your deployment target is iOS 15 or later (or an aligned version of macOS, tvOS, or watchOS), you can use the ViewBuilder version of overlay instead:
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(alignment: .topTrailing) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7)
}
.overlay(alignment: .bottomTrailing) {
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7)
}
.padding()
)
We can use lorem's suggestion to align the symbol centers using a VStack. Then we can factor out the two offset modifiers into a padding on the VStack.
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(
VStack(spacing: 0) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
Spacer()
Image(systemName: "checkmark.square.fill")
}.padding([.top, .bottom, .trailing], -7),
alignment: .trailing)
.padding()
)

Swiftui Custom RoundedRectangle and Overlay Problem

I notice when i use an overlay on a rounded rectangle that there are some parts that are not overlayed, or maybe i'm doing it wrong
and then i tried to switch the view to a regular Iphone SE display, and i notice something that i really dislike, the top is not convered by red
Is there a way to fix it?? or any keyword for me to search? cuz there's probably someone with the same question as i am
Thanks
RoundedRectangle(cornerRadius:25)
.frame(height: 350, alignment:.center)
.foregroundColor(Color("Kolor1"))
.overlay(
ZStack {
Text("Makan")
HStack {
Spacer().frame(width:80)
VStack {
Spacer()
Image("Labtek")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 360, height: 260, alignment:.center)
}
}
}
)
.edgesIgnoringSafeArea(.top)

SwiftUI and WidgetKit image alignment to the right

The code:
VStack(alignment: .trailing) {
Image("Useful")
.resizable()
.ignoresSafeArea()
.scaledToFill()
.frame(width: 105, height: 105)
.padding(.trailing, -60.0)
}
The problem is that image is not at the side and has a small gap near the image and widget as shown in the photo.
How to make this little gap disappear
:)
If I correctly understood your concern, here is possible solution
var body: some View {
Color.clear.overlay(
Image("plant")
.resizable()
.scaledToFill()
.frame(width: 105, height: 105)
, alignment: .bottomTrailing)
}

SwiftUI NavigationView not see Image

I have a code and make NavigationLink Button, I write Text and Image, But my Image not a see. Pls help me.
VStack{
Image("Coachs")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
//.clipped()
.cornerRadius(20.0)
NavigationLink(destination: Text("Detail view here")){
ZStack{
Text("Press on me")
.foregroundColor(.white)
.font(.largeTitle)
Image("Coachs")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
//.clipped()
.cornerRadius(20.0)
}
}}
I make screen if you can't understand
ok, I looked at other image types, try this, it should work:
Image("IMG_4944")
.renderingMode(.original) // <----- this
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
.clipped()
.cornerRadius(20.0)
This looks like SwiftUI bug of handling raster images. Please find below approach for workaround. Tested with Xcode 11.4 / iOS 13.4
This is an example of cell to be used for your goal. Of course in real case the image name and navigation link destination, etc., can be injected via constructor parameters for reuse purpose.
struct TestImageCell: View {
#State private var isActive = false
var body: some View {
Image("large_image") // raster !! image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
.cornerRadius(20.0)
.overlay(
Text("Press on me") // text is over
.foregroundColor(.white)
.font(.largeTitle)
)
.onTapGesture { self.isActive.toggle() } // activate link on image tap
.background(NavigationLink(destination: // link in background
Text("Detail view here"), isActive: $isActive) { EmptyView() })
}
}
I made this test from your code, and all works well, ios 13.4 and catalyst, xcode 11.4 and macos catalina 10.15.4
var body: some View {
NavigationView {
VStack {
Image(systemName: "person.2.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
//.clipped()
.cornerRadius(20.0)
NavigationLink(destination: Text("Detail view here")){
ZStack{
Image(systemName: "person.2.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 370, height: 200)
//.clipped()
.cornerRadius(20.0)
Text("Press on me")
.foregroundColor(.black)
.font(.largeTitle)
}
}
}
}.navigationViewStyle(StackNavigationViewStyle())
}