条件NSString常量

时间:2015-10-07 06:46:25

标签: ios objective-c iphone ipad constants

我将表视图单元格XIB名称声明为NSString常量。 iPad和iPhone有单独的XIB,我想使用相同的常量名称来引用两个版本的XIB,但值不同。

BaseViewController.h

#import <UIKit/UIKit.h>

extern NSString * const FileCell;
extern NSString * const FolderCell;

BaseViewController.m

#import "BaseViewController.h"

//I am sure that this cannot be done 
//since I cannot check device type at preprocessing time/compile time

#if IS_IPAD_DEVICE// device check, not viable
NSString * const FileCell = @"FileCell";
NSString * const FolderCell = @"FolderCell";
#else
NSString * const FileCell = @"FileCell~iPhone";
NSString * const FolderCell = @"FolderCell~iPhone";
#endif

//I don't want to declare separate constants with different names for iPhone table view cells. 
//I want to use same name of constants but the string values are different for iPad and iPhone. 

@implementation BaseViewController

-(void)viewDidLoad
{
    [super viewDidLoad];
    [self.collectionView registerNib:[UINib nibWithNibName:FileCell bundle:nil] forCellWithReuseIdentifier:FileCell];
    [self.collectionView registerNib:[UINib nibWithNibName:FolderCell bundle:nil] forCellWithReuseIdentifier:FolderCell];

}

许多其他文件和子控制器也使用这些常量。 任何想法我怎么能完成这件事。我不想使用属性并覆盖他们的getter。一些优雅的解决方案?

4 个答案:

答案 0 :(得分:0)

可以通过以下几种方式完成:

  1. 在没有自动布局的情况下使用带有支柱/弹簧的一个xibs或使用自动布局为所有屏幕尺寸启用。
  2. 其他方式您必须使用属性或全局变量在屏幕开始时设置NSString的值。
  3. ViewController.h

    @interface ViewController : UIViewController
    
    NSString * FileCell;
    NSString * FolderCell;
    
    @end  
    

    ViewController.m

    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
        {
            FileCell = @"FileCell";
            FolderCell = @"FolderCell";
    
        }else{
            FileCell = @"FileCell~iPhone";
            FolderCell = @"FolderCell~iPhone";
        }
        // Do any additional setup after loading the view, typically from a nib.
    }
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    @end
    

答案 1 :(得分:0)

进口

 @interface ViewController : UIViewController

 extern NSString * FileCell; extern NSString * FolderCell;

 @end

import&#34; ViewController.h&#34;

 @interface ViewController ()

 @end

 @implementation ViewController

 (void)viewDidLoad {
   [super viewDidLoad];

   if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) { 
          FileCell = @"FileCell";  
          FolderCell = @"FolderCell";


   }
  else
    { 
     FileCell = @"FileCell~iPhone"; FolderCell = @"FolderCell~iPhone"; 
     } 

      [self.collectionView registerNib:[UINib nibWithNibName:FileCell bundle:nil] forCellWithReuseIdentifier:FileCell];

       [self.collectionView registerNib:[UINib nibWithNibName:FolderCell bundle:nil] forCellWithReuseIdentifier:FolderCell];
   }


   (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }

  @end

答案 2 :(得分:0)

在程序方法上不是空间。最后,您需要单元格的名称及其标识符。

在iOS 8之前的故事板方法中,我们为iPad和iPhone分别设置了故事板。他们每个人都有自己的布局,因此他们自己的细胞。我认为这是一个更清洁的解决方案。尽管我们试图通用的通用故事板,iPad仍有更多展示空间的空间。因此,对于Android平板电脑应用来说,拉伸内容毫无意义。

我的建议是,拆分iPad和iPhone故事板。他们仍然可以共享相同的课程。毕竟我们的应用程序早在iOS 9之前就已经有了splitview。

答案 3 :(得分:0)

您无法使用#ifdef执行此操作,因为可以在iPhone和iPad上使用相同的可执行文件。

但是你无论如何都不需要#ifdef,因为如果你正确命名你的资源,iOS会自动为iPhone和iPad加载不同的资源文件(包括XIB文件)。 {O-3}}中记录了此行为。

具体来说,在iPhone上,当您要求FileCell.xib时,如果该资源存在,它将自动加载FileCell~iphone.xib。在iPad上,如果该资源存在,它将自动加载FileCell~ipad.xib

请注意,与Mac OS X不同,iOS使用区分大小写文件系统。因此,您只需将FileCell~iPhone.xib重命名为FileCell~iphone.xib,同样适用于您的其他xibs。请注意小写 p