Ответ 1
Переопределить awakeFromNib в вашем представлении - это первый метод жизненного цикла, который вызывается после того, как IBOutlets были назначены, и является правильным местом для вашего кода.
У меня есть пользовательский класс UIView
. Внутри я объявил свойство IBOutlet
для UIImageView
.
#import <UIKit/UIKit.h>
@interface SettingItem : UIView{
}
@property (strong, nonatomic) IBOutlet UIImageView *myImage;
@end
Теперь я использую раскадровку. Существует viewcontroller. Я перетащил UIView
в viewcontroller. Я перетащил один UIImageView
в подзаголовок выше UIView
. Я установил класс "SettingItem" в UIView
из раскадровки. Я подключил выход к myImage путем обычного перетаскивания из выходов SettingItem
из окна служебных программ.
SettingItem
реализация#import "SettingItem.h"
@implementation SettingItem
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self baseInit];
}
return self;
}
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
[self baseInit];
}
return self;
}
- (void) baseInit{
NSLog(@"myImage %@"self.myImage);
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
Теперь моя проблема myImage
всегда nil
, выше NSLog
просто напечатайте (null)
для выхода. Я проверил представление в раскадровке и проверил ее выходную ссылку и указал на myImage
. Я чего-то не хватает. Я искал Google для помощи, но не смог найти решение.
Не могли бы вы указать, что я делаю неправильно?
Переопределить awakeFromNib в вашем представлении - это первый метод жизненного цикла, который вызывается после того, как IBOutlets были назначены, и является правильным местом для вашего кода.
У меня была точно такая же проблема, и решение очень просто:
Вы скоро получите myImage
- это.
При использовании -(id) initWithCoder:(NSCoder *)aDecoder{
и - (id)initWithFrame:(CGRect)frame
UIView
еще не выделен. Так что myImage еще не инициализирован.
Вы можете протестировать его, если добавить UIButton
и IBAction
и сделать что-то вроде этого:
- (IBAction)buttonClicked:(id)sender {
NSLog(@"%@",myImage);
}
И вы увидите, как myImage
больше не nil
.
инициализировать их в awakeFromNib:
- (void)awakeFromNib
{
//init code
}
У меня были подобные проблемы, но я, наконец, выяснил, что не так. Это была разница в идиоме между XIB файлами и Storyboards.
Во всех обучающих программах, которые я видел с Xib файлами, если у меня был UITableViewController, создайте DetailViewController, чтобы я мог редактировать содержимое элементов в таблице, тогда tableViewController создал экземпляр DVC один раз, когда он впервые обнаружил он, но затем повторно использовал тот же самый экземпляр DVC, когда ему нужно было отредактировать другой элемент в списке.
В раскадровках кажется, что представление, которое открывается табличным представлением, обычно создается новым каждый раз, когда представление таблицы вызывает его (и оно не вызывает версию init, которая находится в шаблоне UIViewController), Как было сказано в предыдущем ответе, вам нужно подождать, пока "ViewDidLoad" не получит доступ к любому из элементов управления, даже если вы ранее показывали это представление.
Надеюсь, это поможет.
Вызвать [self baseInit]
внутри -(void)viewWillAppear:(BOOL)animated
. myImage
должен иметь там значение.
#import "SettingItem.h"
@implementation SettingItem
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
}
return self;
}
-(void)viewWillAppear:(BOOL)animated
{
[self baseInit];
}
- (void) baseInit{
NSLog(@"myImage %@"self.myImage);
}
в вашем .h файле вам нужно заменить код:
#import <UIKit/UIKit.h>
@interface SettingItem : UIView{
}
@property (strong, nonatomic) IBOutlet UIImageView *myImage;
@end
С помощью этого кода
#import <UIKit/UIKit.h>
@interface SettingItem : UIView{
IBOutlet UIImageView*myImage;
}
@end
На самом деле вы не говорите Xcode, что такое myImage, вы просто делаете его сильным, неатомным свойством