以前公司项目需要做iPhone和iPad的版本,项目本来是storyboard+代码的模式,但是由于iPhone和ipad的横竖尺寸比例相差太远,以前按照屏幕比例适配的逻辑已经行不通,所以就试着建立两个storyboard,共用一个UIViewController的设计方案,基本上解决了这个问题,如果朋友有其他的的方案,可以给我留个言,我也一直想看看有什么改进的地方
1、StoryBoard项目结构:
创建过程:
1、每一个storyboard都有两个版本,注意,先创建一个(例如叫Home.storyboard),然后按照以下操作创建另外一个:
选中Home.storyboard --> File --> duplicate,在弹出来的窗口,给文件命名Home_ipad.storyboard:(注意一点要设置为_ipad,需要和下面的代码匹配)
2、选中Home_ipad.storyboard,open as ---> source code,找到targetRuntime,将其修改为targetRuntime="iOS.CocoaTouch.iPad"
3、给UIStoryboard创建分类 UIStoryboard (Adapter)
UIViewController+Adapter.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIStoryboard (Adapter)
+(UIStoryboard *_Nullable)storyboardAdapter:(nonnull NSString*)name bundle:(nullable NSBundle*)storyboardBundleOrNil;
@end
NS_ASSUME_NONNULL_END
UIViewController+Adapter.m
#import "UIViewController+Adapter.h"
@implementation UIViewController (Adapter)
- (instancetype)initWithAdapterNibName:(nullable NSString*)nibNameOrNil bundle:(nullable NSBundle*)nibBundleOrNil{
UIViewController*tmpVC;
if((UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)) {
NSString*ipad = [nibNameOrNil stringByAppendingString:@"_ipad"];
tmpVC = [self initWithNibName:ipad bundle:nibBundleOrNil];
}else{
tmpVC = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
return tmpVC;
}
@end
4、使用方法:
eg:
let mainBaseNC = UIStoryboard(adapter: kStoryBoard_Home, bundle: nil)?.instantiateViewController(withIdentifier: "HomeBaseNC") as! ABCBaseNC
二、顺便说说如果是纯代码的项目,对于同时适配iPhone和iPad的图片的使用:
1、runtime 替换系统 imageNamed 方法,同时适配iphone和ipad图片
创建 UIImage 分类
UIImage+Category.h
#import <UIKit/UIKit.h>
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_PAD (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPad)
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (Category)
@end
NS_ASSUME_NONNULL_END
UIImage+Category.m 文件
#import "UIImage+Category.h"
#import <objc/runtime.h>
@implementation UIImage (Category)
+(void)load {
Method imageNamed = class_getClassMethod(self,@selector(imageNamed:));
Method mkeImageNamed =class_getClassMethod(self,@selector(mke_imageNamed:));
method_exchangeImplementations(imageNamed, mkeImageNamed);
}
+(instancetype)mke_imageNamed:(NSString*)name{
// UIImage * image;
if( IS_IPHONE ){
// iphone处理
UIImage * image = [self mke_imageNamed:name];
if (image != nil) {
return image;
}else {
return nil;
}
} else {
// ipad处理
UIImage *image = [self mke_imageNamed:[NSString stringWithFormat:@"%@_ipad",name]];
if (image != nil) {
return image;
}else {
image = [self mke_imageNamed:name];
return image;
}
}
使用:
UIImageView *imageview = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
imageview.image = [UIImage imageNamed:@"icon"];
三、如果是StoryBoard的项目,对于同时适配iPhone和iPad的图片的使用:
使用Assets.xcassets选择图片后->Devices中选择iPhone和iPad(这里借用 Pinkney 哥们的一张图 )