4

I have an Objective-C UIView class:

ChoosePersonView.h

@class Person;

@interface ChoosePersonView : MDCSwipeToChooseView

@property (nonatomic, strong, readonly) Person *person;

- (instancetype)initWithFrame:(CGRect)frame
                       person:(Person *)person
                      options:(MDCSwipeToChooseViewOptions *)options;

@end

MDCSwipeToChooseView.m

@class MDCSwipeToChooseViewOptions;

@interface MDCSwipeToChooseView : UIView

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIView *likedView;
@property (nonatomic, strong) UIView *nopeView;

- (instancetype)initWithFrame:(CGRect)frame
                      options:(MDCSwipeToChooseViewOptions *)options;

@end

Normally I would subclass and use it like the following:

ChoosePersonView.m

@implementation ChoosePersonView

#pragma mark - Object Lifecycle

- (instancetype)initWithFrame:(CGRect)frame
                       person:(Person *)person
                      options:(MDCSwipeToChooseViewOptions *)options {
    self = [super initWithFrame:frame options:options];
    if (self) {
        _person = person;
        self.imageView.image = _person.image;

        self.autoresizingMask = UIViewAutoresizingFlexibleHeight |
                                UIViewAutoresizingFlexibleWidth |
                                UIViewAutoresizingFlexibleBottomMargin;
        self.imageView.autoresizingMask = self.autoresizingMask;

        [self constructInformationView];
    }
    return self;
}

...
@end

The problem I'm facing is when I try to do this in Swift, the property self.imageView is always nil.

I'm not sure how to re-implement initWithFrame as it's implemented in Objective-C within Swift. I thought using init(frame: CGRect, person: Person, options: MDCSwipeToChooseViewOptions) was the correct way but I think I may be wrong.

ChoosePersonView.swift

class ChoosePersonView: MDCSwipeToChooseView {
    var informationView: UIView!
    var nameLabel: UILabel!
    var cameraImageLabelView: ImageLabelView!
    var interestsImageLabelView: ImageLabelView!
    var friendsImageLabelView: ImageLabelView!
    var person: Person!
    let ChoosePersonViewImageLabelWidth = CGFloat(42.0)

    // #pragma mark - Object Lifecycle

    init(frame: CGRect, person: Person, options: MDCSwipeToChooseViewOptions) {
        super.init(frame: frame)

        self.person = person
        self.imageView.image = self.person.image // self.imageView is nil.
        self.autoresizingMask = .FlexibleHeight | .FlexibleWidth | .FlexibleBottomMargin
        self.imageView.autoresizingMask = self.autoresizingMask

        self.constructInformationView()
    }
    ....
}

1 Answer 1

1

self.imageView is nil because you are not doing anything to make it not be nil. You do not show any code that would make it not be nil, so it is hard to guess how you imagine that is supposed to happen.

My guess is that it is the job of MDCSwipeToChooseView's initializer, which you would call as super.init(frame:options:), to create imageView. It's hard to say, because you don't show the code. Certainly, that is the initializer you were calling when ChoosePersonView was written in Objective-C. So why are you not calling it now too, now that it is written in Swift? For some reason, you have elected not to call that initializer - you are calling super.init(frame:) instead. That seems a very strange thing to do. Perhaps that's where you're going wrong.

But in any case I can guarantee you that if you don't call some code that causes imageView not to be nil, it will be nil, because that is the default value for all object properties in Objective-C.

4
  • No, in ObjectiveC it is not "already instantiated". As I said, some code you did not show must have been instantiating it. Things do not instantiate themselves no matter which language you use.
    – matt
    Commented Jul 9, 2014 at 5:13
  • So the problem was that I was calling super.init(frame: frame) instead of super.init(frame: frame, options: options). That was then initialising the necessary imageViews, etc.
    – gotnull
    Commented Jul 9, 2014 at 6:43
  • But that is exactly what I said. Didn't you even read my answer? You accepted it but you didn't even read it or do what I suggested? What's the point of that?
    – matt
    Commented Jul 9, 2014 at 11:39
  • 3
    Easy, fella. What gives you the impression I didn't read your answer? I added a comment simply to confirm the validity of your answer. Are you having a bad day?
    – gotnull
    Commented Jul 9, 2014 at 23:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.