Here , I'm trying to apply same rotation in both these elements.But these object or elements are doing un wanted behaviour, they are not rotating as same as others . So I want to rotate them all as same , So that no the blue card gets behind the image.
I mean I want them all to be in same rotation.
Here my code -
var body: some View {
VStack(spacing : 10){
ZStack {
ZStack (alignment : .bottom){
ZStack(alignment : .bottom){
Image("cat")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: length, height: length)
Text("<>")
.frame(width: 20, height: 20)
.padding()
.background(Color.orange)
.cornerRadius(15)
}
.frame(width: length, height: length)
.background(.blue)
.rotationEffect(Angle(degrees: Double(-totalRotation.width)))
Text("<>")
.frame(width: 20, height: 20)
.padding()
.background(Color.orange)
.cornerRadius(15)
.gesture(
DragGesture()
.onChanged { value in
totalRotation.width = value.translation.width + currentRotation.width
}
.onEnded { value in
currentRotation = totalRotation
mainAngle = totalRotation
}
)
Text("\(mainAngle.width) --- \(totalRotation.width)")
.foregroundColor(.white)
}
.frame(width: length, height: length)
.background(.blue)
.rotationEffect(Angle(degrees: Double(-mainAngle.width)))
}
.frame(width: length, height: length)
.rotationEffect(Angle(degrees: Double(-mainAngle.width)))
}
.frame(width: length, height: length)
Text("\(angle)")
}
}[![Here the image to get much information][1]][1]
Related
I am applying rotation gesture and magnify gesture in a ZStack. But the ZStack is not getting rotated , but the image inside the ZStack is getting rotated and scaled upon the gesture while I did applied the rotation and scale on ZStack.
Here is My Code :
var body: some View {
NavigationView {
VStack {
GeometryReader { geo in
let w = geo.size.width
let h = geo.size.height
let size = getSize(h, w)
if size.width > 0 && size.height > 0 {
ZStack {
Image(uiImage: service.backgroundImage!)
.resizable()
.scaledToFill()
.frame(width: size.width, height: size.height, alignment: .center)
.clipped()
//This is the ZStack --------------------
ZStack{
Image(uiImage: foregroundImage)
.resizable()
.scaledToFit()
.background(GeometryGetter(rect: $imageRect))
}
.rotationEffect(rotationAngle)
.scaleEffect(scale)
.gesture(DragGesture(minimumDistance: 0 , coordinateSpace: .local)
.onChanged { value in
self.offset.x += value.location.x - value.startLocation.x
self.offset.y += value.location.y - value.startLocation.y
print("->> Location - \(value.location)")
})
.offset(x: offset.x, y: offset.y)
.gesture(simultaneous)
.background(.blue)
}
.frame(width: size.width, height: size.height, alignment: .center)
.clipped()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(AppDefaults.Theme.secondaryColor)
}
}
bottomContainerView()
}
.background(Color.black.ignoresSafeArea())
}
}
Add .background(.blue) before .rotationEffect(rotationAngle).
view modifier order matters in swiftUI.
take a look here
A whiteness is seen in the area drawn with the red line. If I change the background color of the most inclusive Vstack, that white area changes.
Deleting spacer() lines doesn't work.
Why is there a gap even though there is no space in between?
struct TabbarView: View {
var body: some View {
VStack{
Spacer()
ZStack{
Color.orange.opacity(0.5)
VStack(spacing: 0){
Text("Home")
.padding()
}
}
Spacer()
HStack{
VStack{
Image(systemName: "homekit")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: UIScreen.main.bounds.size.width / 15, height: UIScreen.main.bounds.size.height / 25)
}
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 13)
.background(Color.purple)
}
.ignoresSafeArea()
// .background(Color.purple.shadow(radius: 2))
}
}
enter image description here
you can add for VStack:
VStack {}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
updated:
struct ContentView: View {
var body: some View {
ZStack {
Color.orange.opacity(0.5)
VStack {
Spacer()
VStack(spacing: 0){
Text("Home")
.padding()
}
Spacer()
HStack {
VStack {
Image(systemName: "homekit")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25, alignment: .center)
.frame(width: UIScreen.main.bounds.size.width / 15, height: UIScreen.main.bounds.size.height / 25)
}
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 13)
.background(Color.purple)
}
}
.ignoresSafeArea()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
you used nesting incorrectly and there is a native TabView for tabs
result:
iam unsing a UiKit Image picker and trying to setup an Profil Pic for the User. Everything's works fine, the image gets displayed. But iam trying to make it into a Circle. I Tried using clipShape with an circle but it doesn't work. i followed the tutorial "My Images 1: Photo Picker and Camera in SwiftUI"
struct ProfileView: View {
#EnvironmentObject var appUser: User
#EnvironmentObject var appInfo: AppInformation
var body: some View {
ZStack {
Rectangle()
.frame(width: 400, height: 720)
.cornerRadius(50)
.foregroundColor(.gray)
.overlay(
HStack {
if let image = appUser.profilBild {
Image(uiImage: image)
.resizable()
.frame(width: 100, height: 100)
.scaledToFill()
.clipShape(RoundedRectangle(cornerRadius: 15))
.overlay(Circle().stroke(Color.orange, lineWidth: 10))
.onTapGesture {
appInfo.source = .library
appInfo.showPicker = true
}
.padding(20)
.shadow(radius: 10)
.overlay(
ZStack{
Rectangle()
.frame(width: 20, height: 20)
.offset(x: 35, y: -35)
.foregroundColor(.white)
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30)
.offset(x: 35, y: -35)
.foregroundColor(.blue)
.shadow(radius: 10)
}
)
}
else {
Image(systemName: "person.circle")
.resizable()
.frame(width: 100, height: 100)
.onTapGesture {
appInfo.source = .library
appInfo.showPicker = true
}
.padding(20)
.shadow(radius: 10)
.overlay(
ZStack{
Rectangle()
.frame(width: 20, height: 20)
.offset(x: 35, y: -35)
.foregroundColor(.white)
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30)
.offset(x: 35, y: -35)
.foregroundColor(.blue)
.shadow(radius: 10)
}
)
}
VStack {
Text(appUser.username)
.font(.largeTitle)
.frame(width: 240 ,alignment: .leading)
.offset(x: -10, y: -25)
.lineLimit(1)
Text(appUser.name)
.frame(width: 220, alignment: .leading)
.offset(x: -15,y: -20)
.lineLimit(1)
}
}
.frame(width: 400, height: 720, alignment: .topLeading)
)
.padding()
ZStack {
Rectangle()
.foregroundColor(.secondary)
.frame(width: 380, height: 510)
.cornerRadius(45)
}
.frame(width: 400, height: 700, alignment: .bottom)
.padding()
}
.sheet(isPresented: $appInfo.showPicker) {
ImagePicker(sourceType: appInfo.source == .library ? .photoLibrary : .camera, selectedImage: $appUser.profilBild)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
}
You were almost there :)
Your only mistake was the order you placed your modifiers. ORDER MATTERS!!
Place scaledToFill() and clipShape() before the frame modifier.
Like such:
.resizable()
.scaledToFill()
.clipShape(Circle())
.frame(width: size, height: size)
My code:
public var body: some View {
ZStack(alignment: .bottom) {
Ellipse()
.fill(.yellow)
Text("Text")
.padding(.bottom, 42)
.foregroundColor(.red)
}
.frame(width: 546, height: 364)
.position(x: UIScreen.main.bounds.size.width / 2, y: Spacing.padding_0_5)
.edgesIgnoringSafeArea(.top)
.background(Color.red)
}
makes ZStack takes almost all screen height. But I expect it will take height from .frame() method.
I have a workaround for you, it's a bit messed up but works
public var body: some View {
ZStack {
ZStack(alignment: .bottom) {
Ellipse()
.fill(.yellow)
}
.frame(width: 546, height: 364)
.position(x: UIScreen.main.bounds.size.width / 2, y: Spacing.padding_0_5)
.edgesIgnoringSafeArea(.top)
.zIndex(0)
ZStack {
VStack {
VStack {
Text("Text")
.padding(.top, 42)
.foregroundColor(.red)
}
.frame(width: UIScreen.main.bounds.width, height: 182)
VStack {
Text("Your texts here")
}
.frame(width: UIScreen.main.bounds.width)
Spacer()
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
.zIndex(1)
}
.background(Color.red)
}
I simply made your ellipse on another layer and text on the other.
ZStack(alignment: .bottom) {
Ellipse()
.fill(.yellow)
}
.frame(width: 546, height: 364)
.position(x: UIScreen.main.bounds.size.width / 2, y: Spacing.padding_0_5)
.edgesIgnoringSafeArea(.top)
.zIndex(0)
The .zIndex(0) makes sure that the view is in the background.
ZStack {
VStack { // This VStack contains all your text
VStack { // First VStack
Text("Text")
.padding(.top, 42)
.foregroundColor(.red)
}
.frame(width: UIScreen.main.bounds.width, height: 182)
VStack { //Second VStack
Text("Your texts here")
}
.frame(width: UIScreen.main.bounds.width)
Spacer()
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
.zIndex(1)
Here, the ZStack takes up the entire screen. We added a VStack which contains your texts.
The first VStack has your main label over the Ellipse, and its frame is hardcoded according to the height of the Ellipse (1/2 the height as the other half of the ellipse is outside the screen).
The second VStack starts from the end of our first VStack which was the functionality needed, finally added a spacer() so that the text is placed at the top rather than middle.
The zIndex(1) makes sure that is placed over the elements at zIndex(0)
swiftui i am learning new. I couldn't align my brain stopped. In the picture I said how I wanted to do this. Can you help?
HStack{
Text("Picture")
.font(.custom("Pacifico-Regular",size: 50))
.padding()
.foregroundColor(Color.white)
.shadow(color: .white, radius: 10, x: 0, y: 0)
Image("1coin").resizable()
.aspectRatio(contentMode: .fit)
.frame(width:30, height: 30)
Text("123")
.font(.custom("Pacifico-Regular",size: 20))
.foregroundColor(Color.white)
}
Here is possible layout (with some replicated components instead of your custom). Prepared with Xcode 12.1 / iOS 14.1
HStack{
Spacer()
Text("Picture")
.font(.custom("Pacifico-Regular",size: 50))
.padding()
.foregroundColor(Color.white)
.shadow(color: .white, radius: 10, x: 0, y: 0)
Spacer().overlay(
HStack {
Image(systemName: "1.circle").resizable()
.foregroundColor(Color.white)
.aspectRatio(contentMode: .fit)
.frame(width:30, height: 30)
Text("123")
.font(.custom("Pacifico-Regular",size: 20))
.foregroundColor(Color.white)
}
, alignment: .trailing)
}
You can use ZStack to embed two HStacks and align them separately.
They will be displayed on top of each other.
You align "Picture" text to the middle - it happens by default.
And then align second HStack with Spacer()
ZStack {
HStack{
Text("Picture")
.font(.custom("Pacifico-Regular",size: 50))
.background(Color.red)
.padding()
.shadow(color: .black, radius: 10, x: 0, y: 0)
}
HStack {
Spacer()
Image("1coin").resizable()
.aspectRatio(contentMode: .fit)
.frame(width:30, height: 30)
.background(Color.red)
Text("123")
.font(.custom("Pacifico-Regular",size: 20))
.background(Color.red)
}
}
If you want to keep all elements at the top, you will need another VStack + Spacer on top of ZStack:
VStack {
ZStack {
HStack{
Text("Picture")
.font(.custom("Pacifico-Regular",size: 50))
.background(Color.red)
.padding()
.shadow(color: .black, radius: 10, x: 0, y: 0)
}
HStack {
Spacer()
Image("1coin").resizable()
.aspectRatio(contentMode: .fit)
.frame(width:30, height: 30)
.background(Color.red)
Text("123")
.font(.custom("Pacifico-Regular",size: 20))
.background(Color.red)
}
}
Spacer()
}