编辑:问题解释
此代码产生一个错误,发布者不知道如何解决。
这是对上一篇文章的新编辑。
我在>几何阅读器。这篇文章包含了所有的代码。这篇新帖子包含了要求的注册和登录代码。我希望它是可读的格式。我做了一些更正,希望能有所帮助。代码如下所示:
import SwiftUI
struct ContentView: View {
var body: some View {
Home()
// for light status bar...
.preferredColorScheme(.dark)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Home : View {
@State var index = 0
var body: some View{
GeometryReader{ _ in // ( ERROR MESSAGE OCCURS HERE)--> ("Type '()' cannot conform to'View'; only struct/enum/class types can conform to protocols" and "Required by generic struct 'GeometryReader' where 'Content' = '()'")
VStack{
Image("logo")
.resizable()
.frame(width:60, height: 60)
ZStack{
SignUp(index: self.$index)
*// changing view order...*
.zIndex(Double(self.index))
Login(index: self.$index)
}
HStack(spacing: 15){
Rectangle()
.fill(Color("Blue"))
.frame(height: 1)
Text("OR")
Rectangle()
.fill(Color("Blue"))
.frame(height: 1)
}
.padding(.horizontal, 20)
.padding(.top, 50)
*// because login button is moved 25 in y axis and 25 padding = 50*
.background(Color("Orange").edgesIgnoringSafeArea(.all))
//Curve...
HStack(spacing: 25){
Button(action: {
}) {
Image("Unknown")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
Button(action: {
}) {
Image("fb")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
Button(action: {
}) {
Image("instagram")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
}
.padding(.top, 30)
}
.padding(.vertical)
struct CShape: Shape {
func path(in rect: CGRect) -> Path {
return Path {path in
*//right side curve...*
path.move(to: CGPoint(x: rect.width, y: 100))
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
path.addLine(to: CGPoint(x: 0, y: rect.height))
path.addLine(to: CGPoint(x: 0, y: 0))
}
}
}
struct CShape1: Shape {
func path(in rect: CGRect) -> Path {
return Path {path in
*//left side curve...*
path.move(to: CGPoint(x: 0, y: 100))
path.addLine(to: CGPoint(x: 0, y: rect.height))
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
path.addLine(to: CGPoint(x: rect.width, y: 0))
}
}
}
struct Login : View {
@State var email = ""
@State var pass = ""
@Binding var index : Int
var body : some View {
ZStack(alignment: .bottom) {
VStack{
HStack{
VStack(spacing:10){
Text("Login")
.foregroundColor(self.index == 0 ? .white : .gray)
.font(.title)
.fontWeight(.bold)
Capsule()
.fill(self.index == 0 ? Color.blue : Color.clear)
.frame(width:100, height: 5)
}
Spacer(minLength:0)
}
.padding(.top, 30)// for top curve...
VStack{
HStack(spacing:15){
Image(systemName: "envelope")
.foregroundColor(Color("Blue"))
TextField("Email Adress", text: self.$email)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 40)
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$pass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
HStack{
Spacer(minLength: 0)
Button(action: {
}) {
Text("Forget Password?")
.foregroundColor(Color.white.opacity(0.6))
}
}
.padding(.horizontal)
.padding(.top, 30)
}
.padding()
// bottom padding...
.padding(.bottom, 65)
.background(Color("LightBlue"))
.clipShape(CShape())
.contentShape(CShape())
.shadow(color: Color.black.opacity(0.3), radius: 5, x: 0, y: -5)
.onTapGesture{
self.index = 0
}
.cornerRadius(35)
.padding(.horizontal,20)
// Button...
Button(action: {
}) {
Text("LOGIN")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.padding(.horizontal, 50)
.background(Color("LightBlue"))
.clipShape(Capsule())
// shadow ...
.shadow(color: Color.white.opacity(0.1), radius: 5, x: 0, y: 5)
}
// moving view down...
.offset(y: 25)
.opacity(self.index == 0 ? 1 : 0)
}
}
}
// SignUp Page...
struct SignUp : View {
@State var email = ""
@State var pass = ""
@State var Repass = ""
@Binding var index: Int
var body : some View {
ZStack(alignment: .bottom) {
VStack{
HStack{
Spacer(minLength:0)
VStack(spacing: 10){
Text("SignUp")
.foregroundColor(self.index == 1 ? .white : .gray)
.font(.title)
.fontWeight(.bold)
Capsule()
.fill(self.index == 1 ? Color.blue : Color.clear)
.frame(width:100, height: 5)
}
}
.padding(.top, 30)// for top curve...
VStack{
HStack(spacing:15){
Image(systemName: "envelope")
.foregroundColor(Color("Orange"))
TextField("Email Adress", text: self.$email)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 40)
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$pass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
// replacing forget password with reenter password...
// so same height will be maintained...
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$Repass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
}
.padding()
// bottom padding...
.padding(.bottom, 65)
.background(Color("Blue"))
.clipShape(CShape1())
//clipping the content shape also for tap gesture...
.contentShape(CShape1())
// shadow...
.shadow(color: Color.black.opacity(0.3), radius: 5, x: 0, y: -5)
.onTapGesture {
self.index = 1
}
.cornerRadius(35)
.padding(.horizontal,20)
*// Button...*
Button(action: {
}) {
Text("SIGNUP")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.padding(.horizontal, 50)
.background(Color("Blue"))
.clipShape(Capsule())
*// shadow ...*
.shadow(color: Color.white.opacity(0.1), radius: 5, x: 0, y: 5)
}
*// moving view down...*
.offset(y: 25)
*// hiding view when its in background...*
*// only button...*
.opacity(self.index == 1 ? 1 : 0)
}
}
}
}
}
}
因此,代码中的问题是在GeomtryReader
中定义视图,这是一个很大的禁忌。因此,解决方案是将Login
和Singup
移动到GeomtryReader
之外,或者更好更好的做法是为每个视图创建一个新文件,并将其代码添加到该文件中。例如,一个文件用于Login.swift
,另一个用于Register.swift
,可能还有另一个名为Shapes
的文件,该文件包括多个形状并将其导出。
你所做的与类似
struct ContentView: View {
var body: some View {
GeomtryReader { _ in
Text("test")
// Here is where the bug would happen
struct NewView: View {
var body: some View {
Text("Second View")
}
}
//////////////////////////////////////
}
}
}
你可以看到,如果你复制并粘贴上面的代码,它会产生同样的错误。您应该做的是将NewView
移出GeomtryReader
像这样的
struct ContentView: View {
var body: some View {
return GeomtryReader { _ in
Text("test")
}
// This will fix the error
struct NewView: View {
var body: some View {
Text("Second View")
}
}
//////////////////////////////////////
}
}
注意我把代码移到了哪里。还要注意,我已经将Return
添加到了GeomtryReader
中,这是因为body
是一个计算属性,它的值为View
,但在这种情况下,我们会混淆编译器,我们希望它是返回值的View
,所以我们必须手动指定它。如果您不想包括return
,那么您必须将NewView
一起移动到body
之外,甚至更好地移动到ContentView
之外。
在任何情况下,这里是你的代码100%工作,你可以复制和粘贴它。
import SwiftUI
struct ContentView: View {
var body: some View {
Home()
// for light status bar...
.preferredColorScheme(.dark)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Home : View {
@State var index = 0
var body: some View{
return GeometryReader{ _ in // ( ERROR MESSAGE OCCURS HERE)--> ("Type '()' cannot conform to'View'; only struct/enum/class types can conform to protocols" and "Required by generic struct 'GeometryReader' where 'Content' = '()'")
VStack{
Image("logo")
.resizable()
.frame(width:60, height: 60)
ZStack{
SignUp(index: self.$index)
// changing view order...*
.zIndex(Double(self.index))
Login(index: self.$index)
}
HStack(spacing: 15){
Rectangle()
.fill(Color("Blue"))
.frame(height: 1)
Text("OR")
Rectangle()
.fill(Color("Blue"))
.frame(height: 1)
}
.padding(.horizontal, 20)
.padding(.top, 50)
// because login button is moved 25 in y axis and 25 padding = 50*
.background(Color("Orange").edgesIgnoringSafeArea(.all))
// Curve...
HStack(spacing: 25){
Button(action: {
}) {
Image("Unknown")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
Button(action: {
}) {
Image("fb")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
Button(action: {
}) {
Image("instagram")
.resizable()
.renderingMode(.original)
.frame(width: 50, height: 50)
.clipShape(Circle())
}
}
.padding(.top, 30)
}
.padding(.vertical)
}
struct Login : View {
@State var email = ""
@State var pass = ""
@Binding var index : Int
var body : some View {
ZStack(alignment: .bottom) {
VStack{
HStack{
VStack(spacing:10){
Text("Login")
.foregroundColor(self.index == 0 ? .white : .gray)
.font(.title)
.fontWeight(.bold)
Capsule()
.fill(self.index == 0 ? Color.blue : Color.clear)
.frame(width:100, height: 5)
}
Spacer(minLength:0)
}
.padding(.top, 30)// for top curve...
VStack{
HStack(spacing:15){
Image(systemName: "envelope")
.foregroundColor(Color("Blue"))
TextField("Email Adress", text: self.$email)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 40)
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$pass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
HStack{
Spacer(minLength: 0)
Button(action: {
}) {
Text("Forget Password?")
.foregroundColor(Color.white.opacity(0.6))
}
}
.padding(.horizontal)
.padding(.top, 30)
}
.padding()
// bottom padding...
.padding(.bottom, 65)
.background(Color("LightBlue"))
.clipShape(CShape())
.contentShape(CShape())
.shadow(color: Color.black.opacity(0.3), radius: 5, x: 0, y: -5)
.onTapGesture{
self.index = 0
}
.cornerRadius(35)
.padding(.horizontal,20)
// Button...
Button(action: {
}) {
Text("LOGIN")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.padding(.horizontal, 50)
.background(Color("LightBlue"))
.clipShape(Capsule())
// shadow ...
.shadow(color: Color.white.opacity(0.1), radius: 5, x: 0, y: 5)
}
// moving view down...
.offset(y: 25)
.opacity(self.index == 0 ? 1 : 0)
}
}
}
//SignUp Page...
struct SignUp : View {
@State var email = ""
@State var pass = ""
@State var Repass = ""
@Binding var index: Int
var body : some View {
ZStack(alignment: .bottom) {
VStack{
HStack{
Spacer(minLength:0)
VStack(spacing: 10){
Text("SignUp")
.foregroundColor(self.index == 1 ? .white : .gray)
.font(.title)
.fontWeight(.bold)
Capsule()
.fill(self.index == 1 ? Color.blue : Color.clear)
.frame(width:100, height: 5)
}
}
.padding(.top, 30)// for top curve...
VStack{
HStack(spacing:15){
Image(systemName: "envelope")
.foregroundColor(Color("Orange"))
TextField("Email Adress", text: self.$email)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 40)
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$pass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
// replacing forget password with reenter password...
// so same height will be maintained...
VStack{
HStack(spacing:15){
Image(systemName: "eye")
.foregroundColor(Color("Orange"))
SecureField("Password", text: self.$Repass)
}
Divider().background(Color.white.opacity(0.5))
}
.padding(.horizontal)
.padding(.top, 30)
}
.padding()
// bottom padding...
.padding(.bottom, 65)
.background(Color("Blue"))
.clipShape(CShape1())
//clipping the content shape also for tap gesture...
.contentShape(CShape1())
// shadow...
.shadow(color: Color.black.opacity(0.3), radius: 5, x: 0, y: -5)
.onTapGesture {
self.index = 1
}
.cornerRadius(35)
.padding(.horizontal,20)
// Button...*
Button(action: {
}) {
Text("SIGNUP")
.foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.padding(.horizontal, 50)
.background(Color("Blue"))
.clipShape(Capsule())
// shadow ...*
.shadow(color: Color.white.opacity(0.1), radius: 5, x: 0, y: 5)
}
// moving view down...*
.offset(y: 25)
// hiding view when its in background...*
// only button...*
.opacity(self.index == 1 ? 1 : 0)
}
}
}
struct CShape: Shape {
func path(in rect: CGRect) -> Path {
return Path {path in
//right side curve...*
path.move(to: CGPoint(x: rect.width, y: 100))
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
path.addLine(to: CGPoint(x: 0, y: rect.height))
path.addLine(to: CGPoint(x: 0, y: 0))
}
}
}
struct CShape1: Shape {
func path(in rect: CGRect) -> Path {
return Path {path in
//left side curve...*
path.move(to: CGPoint(x: 0, y: 100))
path.addLine(to: CGPoint(x: 0, y: rect.height))
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
path.addLine(to: CGPoint(x: rect.width, y: 0))
}
}
}
}
}