xcode 使特定于 iPhone 的应用程序在 iPad 上运行以满足 Apple 的要求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10527781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 00:15:56  来源:igfitidea点击:

Make an iPhone specific app work on iPad to meet Apple requirements

iphoneiosxcodeapp-storeappstore-approval

提问by Sean

My app has been in the AppStore for a couple of months now and always only worked on iPhone. I recently submitted an update which was rejected because the App does not run on an iPad. The exact reason it was rejected was:

我的应用程序已经在 AppStore 上架了几个月,而且总是只能在 iPhone 上运行。我最近提交了一个被拒绝的更新,因为该应用程序不能在 iPad 上运行。它被拒绝的确切原因是:

Reasons for Rejection: 2.10: iPhone apps must also run on iPad without modification, at iPhone resolution, and at 2X iPhone 3GS resolution

拒绝原因: 2.10:iPhone 应用程序也必须在 iPad 上未经修改、以 iPhone 分辨率和 2X iPhone 3GS 分辨率运行

What do I need to do in Xcode to make my app run on an iPad in the little box with the 2X icon?

我需要在 Xcode 中做什么才能使我的应用程序在带有 2X 图标的小框中在 iPad 上运行?

Any tips instructions will be massively appreciated...

任何提示说明将不胜感激...

EDITThis is my info.plist. This is my first App and I think I did initially chose to set it up with "universal" selected. Is there an easy way back for me to rectify this now?

编辑这是我的 info.plist。这是我的第一个应用程序,我想我最初选择设置它并选择“通用”。我现在有什么简单的方法可以纠正这个问题吗?

PLIST contents...

PLIST 内容...

采纳答案by Caleb

Start by figuring out why your app doesn't work on the iPad already. Most apps developed for the iPhone will work fine on an iPad (in compatibility mode) with no modification; if yours doesn't, you must be doing something to prevent it. Are you relying on some hardware feature? Making unfounded assumptions about the device you're running on? How does your app fail when run on an iPad?

首先弄清楚为什么您的应用程序无法在 iPad 上运行。大多数为 iPhone 开发的应用程序无需修改即可在 iPad 上正常运行(在兼容模式下);如果你的没有,你必须做些什么来防止它。您是否依赖某些硬件功能?对正在运行的设备做出毫无根据的假设?在 iPad 上运行时,您的应用程序如何失败?

Once you've figured out why it doesn't work, you'll be much closer than you are now to fixing the problem.

一旦你弄清楚为什么它不起作用,你就会比现在更接近解决问题。

回答by hotpaw2

To get your app to run on an iPad in iPhone compatibility mode, you need to build your app for iPhone only.

要让您的应用程序以 iPhone 兼容模式在 iPad 上运行,您只需要为 iPhone 构建您的应用程序。

Remove all the iPad references from the app's plist (nib base, xib and storyboard), and from the Target Build Settings Targeted Device Family.

从应用程序的 plist(nib base、xib 和 storyboard)和 Target Build Settings Targeted Device Family 中删除所有 iPad 引用。

回答by Sudheer Arakkal

I had the same issue, I was able to run my app on the ipad after making the following changes.

我遇到了同样的问题,在进行以下更改后,我能够在 ipad 上运行我的应用程序。

  1. in the project settings made the Devices to iPhone(it was universal before)
  2. in the .plist removed the main story board file base name related to ipad.
  1. 在项目设置中将设备设置为 iPhone(以前是通用的)
  2. 在 .plist 中删除了与 ipad 相关的主故事板文件基本名称。

回答by Nirav

I have solved same issue using this scenario.

我已经使用这个场景解决了同样的问题。

You should check for normal and retina images in your resources folder.

您应该检查资源文件夹中的正常和视网膜图像。

You may also get this error while debugging Could not load the "image.png" image referenced from a nib in the bundle with identifier.

调试时您也可能会收到此错误Could not load the "image.png" image referenced from a nib in the bundle with identifier

A normal iPhone app must run on the iPad in both(1x and 2x) mode without modification. You can check this with the SDK Simulator.

一个普通的 iPhone 应用程序必须在 iPad 上以两种(1x 和 2x)模式运行,无需修改。您可以使用 SDK Simulator 进行检查。

There is a long list in the App Store Review Guidelines on Apple's iOS Developer Portal Center which lists many of the things that Apple reviews this things when you submit an app. Read it carefully.

Apple 的 iOS Developer Portal Center 上的 App Store Review Guidelines 中有一个很长的列表,其中列出了 Apple 在您提交应用程序时对这些内容进行审核的许多内容。仔细阅读。

回答by Jasper

I'll try to explain what my problem and solution was..

我会试着解释我的问题和解决方案是什么..

I have an iPhoneonly app which is mostly in portrait, however, because of 1 or 2 UIViewControllerswhich have to be in all UIInterfaceOrientations, I have to enable all UIInterfaceOrientationsin my plist.

我只有一个iPhone主要是纵向的应用程序,但是,由于必须包含 1 或 2 个UIViewControllers,因此UIInterfaceOrientations我必须UIInterfaceOrientations在我的plist.

When starting the app on an iPadwhich is rotated in landscape and is lying on the table (so has UIDeviceOrientationFaceUp), the whole app was shown in landscape, which made my UI totally messed up.

iPad在横向旋转并躺在桌子上(所以有UIDeviceOrientationFaceUp)上启动应用程序时,整个应用程序以横向显示,这使我的用户界面完全混乱。

I had no reference to any iPad related code / settings in my plist or launch screens whatsoever (I am using .xcassets for launch screens).

我在我的 plist 或启动屏幕中没有提到任何与 iPad 相关的代码/设置(我使用 .xcassets 作为启动屏幕)。

I fixed it by adding 1 line of code to my AppDelegate.mwhich sets the statusbar orientation to force the app in portrait mode.

我通过向 my 添加 1 行代码来修复它,AppDelegate.m它设置状态栏方向以强制应用程序处于纵向模式。

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];

    //Further setup
}

回答by Jim Rota

I had the same issue using Cocos2d 2.0

我在使用 Cocos2d 2.0 时遇到了同样的问题

My problem was that the project had evolved over several years and had carried along some now vestigial files like RootViewController and UIViewController and MyRootViewController, etc.

我的问题是该项目已经发展了几年,并且已经携带了一些现在残留的文件,例如 RootViewController 和 UIViewController 以及 MyRootViewController 等。

They worked at the time but clearly had raised a flag with today's review committee because I received the "All iPhone apps must work on the iPad" rejection notice. After screaming out loud and finally accepting defeat, I thought that policy makes it pretty hard to make an app iPhone only. Let me know if I am wrong about this.

他们当时在工作,但显然已经向今天的委员会提出了警告,因为我收到了“所有 iPhone 应用程序必须在 iPad 上运行”的拒绝通知。在大声尖叫并最终接受失败之后,我认为该政策使得仅制作 iPhone 应用程序变得非常困难。如果我错了,请告诉我。

Even though I was (and am still) perturbed about it, I thought perhaps now I could at least clean up the project with a more elegant solution that handles the base problem: device rotation + content rotation. I ended up using something from a more recent project that was working on and seemed more elegant and actually worked: simply add MyNavigationController to the top of my AppDelegate.

尽管我(现在仍然)对此感到不安,但我想也许现在我至少可以用一个更优雅的解决方案来清理项目,该解决方案可以解决基本问题:设备旋转 + 内容旋转。我最终使用了一个最近的项目中的一些东西,该项目看起来更优雅且实际有效:只需将 MyNavigationController 添加到我的 AppDelegate 的顶部。

I have added the code below. I am sure it can be improved. Please comment if you can enhance it.

我在下面添加了代码。我相信它可以改进。如果您可以增强它,请发表评论。

As a result, I was able to delete the old RootViewController and MyRootViewController files so now it's easier to maintain. I never understood their purpose very well anyways. Good riddance!

结果,我能够删除旧的 RootViewController 和 MyRootViewController 文件,因此现在更易于维护。无论如何,我从来没有很好地理解他们的目的。甩掉包袱!

Here is my solution to displaying and matching device orientation + content orientation:

这是我显示和匹配设备方向 + 内容方向的解决方案:

in AppDelegate.h I had to declare what I was doing:

在 AppDelegate.h 我必须声明我在做什么:

//top of the file

//文件顶部

@interface MyNavigationController : UINavigationController @end

@interface MyNavigationController : UINavigationController @end

//inside AppDelegate.h interface

//在AppDelegate.h接口内

MyNavigationController *navController_;

MyNavigationController *navController_;

//bottom of the file before @end

//@end之前的文件底部

@property (readonly) MyNavigationController *navController;

@property (readonly) MyNavigationController *navController;

Here is the code that works at the top of my AppDelegate.m

这是在我的 AppDelegate.m 顶部工作的代码

@implementation MyNavigationController

@implementation MyNavigationController

// The available orientations should be defined in the Info.plist file.
// And in iOS 6+ only, you can override it in the Root View controller in the "supportedInterfaceOrientations" method.
// Only valid for iOS 6+. NOT VALID for iOS 4 / 5.

-(NSUInteger)supportedInterfaceOrientations {

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

if (orientation == UIDeviceOrientationPortrait) {

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

        // [director_ pushScene: [IPAD scene]];

    } else {

        [[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];

        return UIInterfaceOrientationMaskPortrait;

    }


} else if (orientation == UIDeviceOrientationLandscapeLeft) {


    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

       //  [director_ pushScene: [IPAD scene]];

    } else {

        [[CCDirectorIOS sharedDirector] pushScene:[MainMenuScene scene]];

    }



} else if (orientation == UIDeviceOrientationLandscapeRight) {


    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

        // [director_ pushScene: [IPAD scene]];

    } else {

        [[CCDirectorIOS sharedDirector] pushScene:[MainMenuScene scene]];

    }


} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

    } else {

        [[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];

        return UIInterfaceOrientationMaskPortraitUpsideDown;

    }

} else {

    //do nothing
}

return UIInterfaceOrientationMaskLandscape;

}

}

//this is the one for iOS 6
- (BOOL)shouldAutorotate {

//NSLog(@"MyNavigationController - should Rotate ToInterfaceOrientation ...");

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ) {

    //NSLog(@"MyNavigationController - should Rotate iPhone");

    if (orientation == UIDeviceOrientationPortrait) {

        //NSLog(@"should Rotate iPhone orientation is Portrait");

        [[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];

        return UIInterfaceOrientationMaskPortrait;

    }

    if (orientation == UIDeviceOrientationPortraitUpsideDown) {

        //NSLog(@"should Rotate iPhone orientation is PortraitUpsideDown");

        [[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];

        return UIInterfaceOrientationMaskPortraitUpsideDown;

    }

    if (orientation == UIDeviceOrientationLandscapeLeft) {

        //NSLog(@"should Rotate iPhone orientation is Landscape Left");

        return UIInterfaceOrientationMaskLandscape;
    }

    if (orientation == UIDeviceOrientationLandscapeRight) {

        //NSLog(@"should Rotate iPhone orientation is Landscape Right");

        return UIInterfaceOrientationMaskLandscape;
    }


    return TRUE;

}

//return UIInterfaceOrientationIsLandscape(interfaceOrientation);

if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ) {

    //NSLog(@"MyNavigationController - should Rotate iPad");

    return TRUE;

}


return TRUE;
}


// Supported orientations. Customize it for your own needs
// Only valid on iOS 4 / 5. NOT VALID for iOS 6.
- (BOOL)shouldAutorotateToInterfaceOrientation:    (UIInterfaceOrientation)interfaceOrientation
{

// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )


    return TRUE;
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);


if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad )

    return TRUE;

// iPad only
// iPhone only
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);

return TRUE;
}

// This is needed for iOS4 and iOS5 in order to ensure
// that the 1st scene has the correct dimensions
// This is not needed on iOS6 and could be added to the application:didFinish...
-(void) directorDidReshapeProjection:(CCDirector*)director
{
if(director.runningScene == nil) {
    // Add the first scene to the stack. The director will draw it immediately into the framebuffer. (Animation is started automatically when the view is displayed.)
    // and add the scene to the stack. The director will run it when it automatically when the view is displayed.
    [director runWithScene: [MainMenuScene scene]];
}
}


-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// Assuming that the main window has the size of the screen
// BUG: This won't work if the EAGLView is not fullscreen

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect rect = CGRectZero;

//NSLog(@"MyNavigationController - Will RotateToInterfaceOrientation ...");

if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)  {

    rect = screenRect;


} else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {

    rect.size = CGSizeMake( screenRect.size.height, screenRect.size.width );

}

CCDirector *director = [CCDirector sharedDirector];
CCGLView *glView = (CCGLView *)[director view];
glView.frame = rect;
}

@end

Here is why I had to solve this:

这就是我必须解决这个问题的原因:

  1. I needed both Landscape and Portrait modes to display different scenes.
  1. 我需要横向和纵向模式来显示不同的场景。

Here are some screenshots that describe the situation

以下是一些描述情况的屏幕截图

JR Chemistry Set

JR 化学套装

most of the app orientation is landscape like this photo shows

大多数应用程序方向都是横向的,就像这张照片所示

other areas were only triggered when you turned the device

其他区域仅在您转动设备时触发

2 apps in one!

2 个应用程序合二为一!