SwiftUI - 画布超出屏幕宽度 - 应用被拒绝
Posted
技术标签:
【中文标题】SwiftUI - 画布超出屏幕宽度 - 应用被拒绝【英文标题】:SwiftUI - Canvas exceeding screen width - App Rejected 【发布时间】:2019-10-25 01:32:48 【问题描述】:基于登录屏幕超出 iPad 显示屏边界的问题,我的应用在提交到应用商店时被拒绝了两次。我已尝试在模拟器或物理 iPad 上重现此问题
Apple 向我发送了以下回复
From Apple
4. Design: Preamble
Guideline 4.0 - Design
We noticed that the login screen of your app was still crowded or laid out in a way that made it difficult to use your app.
We launched the app on iPad (6th generation) running ios 13.1.3 on Wifi.
Next Steps
To resolve this issue, please revise your app to ensure that the content and controls on the screen are easy to read and interact with.
Resources
For more information, please review the following resources on the iOS Developer Center page:
- UI Do's and Don'ts
- iOS Human Interface Guidelines
- UIKit
Please see attached screenshot for details.
我无法复制这个。这是我的代码:
登录.swift
import SwiftUI
struct Login: View
@EnvironmentObject var session: SessionStore
@ObservedObject private var kGuardian = KeyboardGuardian(textFieldCount: KeyboardGuardian.KeyboardSlots.count.rawValue)
@State var email: String = ""
@State var password: String = ""
@State var loading = false
@State var error = false
func getUser ()
session.listen()
func signIn ()
loading = true
error = false
session.signIn(email: email, password: password) (result, error) in
self.loading = false
if error != nil
self.error = true
else
self.email = ""
self.password = ""
var body: some View
VStack
Image("Cloud Pager")
.resizable()
.foregroundColor(.white)
.aspectRatio(contentMode: ContentMode.fill)
.padding()
Text("Cloud Pager")
.font(.largeTitle)
.foregroundColor(.white)
.bold()
.padding(Edge.Set.bottom, 30)
Spacer()
ZStack(alignment: .leading)
Text("Email")
.foregroundColor(email.isEmpty ? .white : .black)
.fontWeight(email.isEmpty ? .regular : .bold)
.padding(.leading, 10)
.offset(y: email.isEmpty ? 0 : -30)
TextField("", text:$email)
.background(Color.clear)
.foregroundColor(.white)
.textContentType(.emailAddress)
.keyboardType(.emailAddress)
.padding(.leading, 10)
.padding(.trailing, 10)
Rectangle()
.frame(height: 3.0, alignment: .bottom)
.foregroundColor(Color.white)
.padding(.bottom, 40)
.padding(.leading, 10)
.padding(.trailing, 10)
ZStack(alignment: .leading)
Text("Password")
.foregroundColor(password.isEmpty ? .white : .black)
.fontWeight(password.isEmpty ? .regular : .bold)
.padding(.leading, 10)
.offset(y: password.isEmpty ? 0 : -30)
SecureField("", text:$password)
.background(Color.clear)
.foregroundColor(.white)
.textContentType(.password)
.padding(.leading, 10)
.padding(.trailing, 10)
Rectangle()
.frame(height: 3.0, alignment: .bottom)
.foregroundColor(Color.white)
.padding(.bottom, 50)
.padding(.leading, 10)
.padding(.trailing, 10)
VStack
Button(action: signIn)
HStack(alignment: .center)
Spacer()
if loading
ActivityIndicator()
else
Text("Sign In")
.foregroundColor(.blue)
.bold()
Spacer()
.padding().background(Color.white).cornerRadius(30.0)
.padding(Edge.Set.bottom, 8)
.padding()
.background(Color.blue.edgesIgnoringSafeArea(.all))
.statusBar(hidden: true)
.onAppear(perform: getUser)
.offset(y: kGuardian.slide).animation(.easeInOut(duration: 0.5))
struct ActivityIndicator: UIViewRepresentable
func makeUIView(context: Context) -> UIActivityIndicatorView
let v = UIActivityIndicatorView()
return v
func updateUIView(_ activityIndicator: UIActivityIndicatorView, context: Context)
activityIndicator.startAnimating()
struct Login_Previews: PreviewProvider
static var previews: some View
Login()
.environmentObject(SessionStore())
在我运行应用程序的每个 iPad 模拟器(以及物理的第 6 代 iPad)上,我无法复制上面的屏幕截图。我的总是这样:
谁能弄清楚这里发生了什么。我的应用设置设置为仅在 iPhone 和 iPad 设备上的纵向
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>
【问题讨论】:
如果你创建一个最小的项目并添加一个链接而不是这个依赖代码会很好。 我在 github 上有整个项目,但由于它包括 firebase 配置文件,所以 repo 是私有的。 不需要整个项目。只是他的页面链接到静态数据。 我不完全确定你要的是什么。 整个答案只是改变了两个字符。 fill -> fit 【参考方案1】:问题在于图像配置。您应该在其中添加以下修饰符:
.scaledToFit()
或只是将内容模式更改为适合
.aspectRatio(contentMode: .fit)
之前 -> 之后
请注意,所有内容都无法调整大小,最好将其中一些设为固定大小。
建议:
对于这样的页面,将所有内容放在一个容器中,并给它maxWidth
和maxHeight
。您不希望您的设计扩展到使用第二个屏幕选项显示您的应用的整个 100 英寸电视,是吗?
注意 2:您使用的图像非常接近来自 Apple 的 受版权保护 图标,下次苹果可能会因为以下原因拒绝您的应用那。保重。
【讨论】:
感谢您的回答。你如何让模拟器在画布之外缩放?我想测试你的答案,但我一开始就无法复制这个问题。 将此代码(在问题中)复制到一个全新的项目中并修复所有错误以使其独立。 创建了一个新项目。放入代码并修复错误。在 iPad 6th gen 和 iPhone 11 模拟器上编译并运行。两者都没有超过你的画布https://imgur.com/a/0f2Llhp
已排序。它没有在我的模拟器上显示的原因是我运行的是 xcode 11 而不是 11.1,因为 11.1 安装有错误。删除了安装并升级到 11.1,它显示了扩展的画布,就像你的一样。答案很完美,干杯。
我会在允许的时候奖励赏金(10 小时)【参考方案2】:
有几件事。
是 .aspectRatio(contentMode: ContentMode.fill) 将顶层 VStack 扩展到屏幕边界之外。
所以你必须把它改成:
.aspectRatio(contentMode: ContentMode.fit)
这似乎可以解决问题:
但是,如果你在模拟器中运行它并旋转 iPad 几次,你会发现你的蓝色背景没有正确重绘:
[
要解决这个问题,您可以将所有内容包装在 ZStack 中:
var body: some View
ZStack
Color.blue
VStack
Image("Cloud Pager")
// etc
.padding()
.statusBar(hidden: true)
.onAppear(perform: getUser)
.offset(y: kGuardian.slide).animation(.easeInOut(duration: 0.5))
.edgesIgnoringSafeArea(.all)
【讨论】:
以上是关于SwiftUI - 画布超出屏幕宽度 - 应用被拒绝的主要内容,如果未能解决你的问题,请参考以下文章