【问题标题】:Issue with initWithFrame when subclassing UIView in Swift在 Swift 中子类化 UIView 时出现 initWithFrame 问题
【发布时间】:2014-07-09 04:24:27
【问题描述】:

我有一个 Objective-C UIView 类:

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

通常我会继承并像下面这样使用它:

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

我面临的问题是,当我尝试在 Swift 中执行此操作时,self.imageView 属性始终为 nil

我不确定如何重新实现 initWithFrame,因为它是在 Swift 中的 Objective-C 中实现的。我认为使用init(frame: CGRect, person: Person, options: MDCSwipeToChooseViewOptions) 是正确的方法,但我想我可能错了。

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()
    }
    ....
}

【问题讨论】:

    标签: uiview swift subclassing


    【解决方案1】:

    self.imageView 为 nil,因为您没有做任何事情使其不为 nil。您没有显示任何使其不为 nil 的代码,因此很难猜测您想象的应该如何发生。

    我的猜测是MDCSwipeToChooseView 的初始化程序(您可以将其称为super.init(frame:options:))的工作是创建imageView。很难说,因为你没有显示代码。当然,这就是您在用 Objective-C 编写 ChoosePersonView 时正在调用的初始化程序。那么,既然它是用 Swift 编写的,为什么你现在不调用它呢?出于某种原因,您选择不调用该初始化程序 - 您正在调用 super.init(frame:)。这似乎是一件很奇怪的事情。也许这就是你出错的地方。

    但无论如何我可以向你保证,如果你不调用 some 导致imageView 不为零的代码,它将为零,因为这是所有的默认值Objective-C 中的对象属性。

    【讨论】:

    • 不,在 ObjectiveC 中它不是“已经实例化”的。正如我所说,您没有显示的某些代码一定是在实例化它。无论您使用哪种语言,事物都不会自行实例化。
    • 所以问题是我打电话给super.init(frame: frame)而不是super.init(frame: frame, options: options)。然后初始化必要的 imageViews 等。
    • 但这正是我所说的。你连我的回答都没看吗?您接受了它,但您甚至没有阅读它或按照我的建议去做?这有什么意义?
    • 简单,伙计。是什么让您觉得我没有阅读您的答案?我添加了一条评论只是为了确认您的答案的有效性。你今天过得很糟糕吗?
    猜你喜欢
    • 1970-01-01
    • 2014-08-21
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    相关资源
    最近更新 更多