SwiftUI - Холст, превышающий ширину экрана - Приложение отклонено - PullRequest
2 голосов
/ 25 октября 2019

Мое приложение было отклонено дважды при отправке в магазин приложений из-за проблемы, когда экран входа в систему выходит за пределы экрана 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.

Clipped login screen

Я не могу повторить это. Вот мой код:

Login.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, на котором я запускаю приложение (и физический iPad 6-го поколения), я не могу скопировать приведенный выше снимок экрана. Мои всегда выглядят так:

Non clipped screenshot

Может кто-нибудь выяснить, что здесь происходит. Настройки моего приложения установлены на Портрет только на устройствах 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>

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Есть несколько вещей.

.aspectRatio (contentMode: ContentMode.fill) расширяет верхний уровень VStack за пределы экрана.

image pushing vstack out of bounds

Так что вы должны изменить его на:

.aspectRatio(contentMode: ContentMode.fit)

Что, кажется, делает трюк:

image drawn correctly

Но, если вы запустите его в симуляторе и поверните iPad несколько раз, вы заметите, что ваш синий фон перерисовывается неправильно:

[background problem[3]

Чтобы исправить это, вы можете обернуть все в 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)
}
1 голос
/ 27 октября 2019

Проблема с конфигурацией изображения. Вы должны добавить к нему следующий модификатор:

.scaledToFit()

или просто изменить режим содержимого на fit

.aspectRatio(contentMode: .fit)

До -> После

Before After

Обратите внимание, что все не может быть изменяемого размера, и этовсегда лучше сделать некоторые из них фиксированного размера.

Предложение:

для таких страниц, поместите все в контейнер и дайте ему maxWidth и maxHeight. Вы не хотите, чтобы ваш дизайн масштабировался, чтобы заполнить весь 100-дюймовый телевизор, показывая ваше приложение, используя второй вариант экрана, не так ли?

Примечание 2 : изображение, которое выВы используете очень близко к защищенному авторским правом значку от Apple, возможно, в следующий раз яблоко отклонит ваше приложение из-за этого. Береги себя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...