2013-08-19 2 views
0

Где большинство программистов указывают, как должны быть большие рамки? Я пытался поставить следующий код в разделе переменные экземпляра .h файлаГде лучшее место для определения размеров рамки для subviews?

CGRect backButtonRect = CGRectMake(2 * w/25, 18 * h/25, 6 * w/25, 2 * h/25); 

, но она не позволит мне по какой-то причине. Я хочу поместить параметры в место, которое легко запомнить, поэтому я могу его отладить позже.

+0

Это не позволит вам сделать это, потому что вы не можете определить переменную экземпляра при ее объявлении. – Abizern

+0

Какой странный язык. – Jessica

+0

@eeeeeeeeee Нет, это не странно, вы просто понимаете его дизайн. Вы можете переместить их в метод initWithXXX: 'или' #define BACK_BUTTON_RECT ((CGRect) {x, y, w, h}) '. –

ответ

4

Вы не можете инициализировать переменную экземпляра в своем объявлении. Это как раз Objective-C. В этом отношении он отличается от Java или C# (или C++ 11). Все переменные экземпляра инициализируются до нуля.

Вы не сказали, какой класс содержит эту переменную экземпляра.

Если вы загружаете объект из XIB или раскадровки, не имеет значения, какой класс он есть; он будет инициализирован, получив сообщение initWithCoder:. Итак, инициализируйте backButtonRect в initWithCoder:. Пример:

- (instancetype)initWithCoder:(NSCoder *)aDecoder { 
    if ((self = [super initWithCoder:aDecoder])) { 
     CGFloat w = 100, h = 64; 
     backButtonRect = CGRectMake(2 * w/25, 18 * h/25, 6 * w/25, 2 * h/25); 
    } 
    return self; 
} 

В качестве альтернативы, если вы не будете знать w и h, пока все ваши выходы подключены, инициализировать backButtonRect в awakeFromNib:

- (void)awakeFromNib { 
    [super awakeFromNib]; 
    backButtonRect = CGRectMake(2 * w/25, 18 * h/25, 6 * w/25, 2 * h/25); 
} 

Если вы создаете объект в коде , то имеет значение, какой класс он есть. Если это UIView подкласс, назначенный инициализатор initWithFrame:, так что это хороший способ, чтобы переопределить для инициализации:

- (instancetype)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     CGFloat w = 100, h = 64; 
     backButtonRect = CGRectMake(2 * w/25, 18 * h/25, 6 * w/25, 2 * h/25); 
    } 
    return self; 
} 

Если это UIViewController подкласс, то назначенный инициализатор initWithNibName:bundle:.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 
     CGFloat w = 100, h = 64; 
     backButtonRect = CGRectMake(2 * w/25, 18 * h/25, 6 * w/25, 2 * h/25); 
    } 
    return self; 
} 
+0

Благодарим вас за это объяснение. – Jeremy

+0

Да. Хорошая работа по объяснению сложного бита с помощью initWithCoder. – Abizern

0

Вы должны стараться не иметь четких определений фреймов в любом месте. Если они вам понадобятся, то их размещение в XIB с определением вида является хорошим. Если вы хотите указать кадры в коде, вы должны попытаться сделать вещи пропорциональными и динамическими, чтобы были заданы размеры некоторых вещей, но большинство вещей вычисляется на основе кадра супервизора и вещей со статическими размерами. Это поддерживает модификации в будущем для немного разных размеров экрана.

Для вещей, которые вам нужно указать, добавление #define в начало файла .m - это хорошо. Хорошо называть их капиталами и подчеркиваниями, чтобы вы могли отчетливо видеть, когда читаете код, что они определены константами.