tl;博士:我如何告诉Swift我正在覆盖MyViewController
view
属性UIView
的子类?
我非常喜欢为UIView
视图提供UIViewController
的子类。例如:
// MyView --------------------------------------------------------
@interface MyView: UIView
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation MyView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_tableView = [[UITableView alloc] initWithFrame:frame];
}
return self;
}
@end
// MyViewController ----------------------------------------------
@interface MyViewController: UIViewController <UITableViewDataSource>
@property (nonatomic, retain) MyView *view;
@end
@implementation MyViewController
- (void)loadView {
self.view = [[MyView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.tableView.dataSource = self;
// etc.
}
@end
这很好,因为它将视图创建和布局逻辑与视图控制器分开。好的,很好。
我可以想象,这就像这样转换成Swift:
// MyView --------------------------------------------------------
class MyView: UIView {
let tableView: UITableView!
init(frame: CGRect) {
super.init(frame: frame)
tableView = UITableView(frame: frame)
}
}
// MyViewController ----------------------------------------------
class MyViewController: UIViewController, UITableViewDataSource {
override func loadView() {
view = MyView(frame: UIScreen.mainScreen().bounds)
}
override func viewDidLoad() {
super.viewDidLoad()
// this causes the compiler to complain with:
// 'UIView' does not have a member named 'tableView'
self.view.tableView.dataSource = self
}
}
麻烦的是我似乎无法弄清楚如何告诉视图控制器它的view
是MyView
的实例,而不是UIView
本身。
这是我到目前为止所尝试的内容:
我在MyViewController
的顶部尝试过此操作,但出现以下错误:
override var view: MyView!
// error: Cannot override mutable property 'view' of
// type 'UIView' with covariant type 'MyView!'
我在loadView
尝试了这个,但没有运气:
view = MyView(frame: UIScreen.mainScreen().bounds) as MyView
// this produces the same error as in the original code:
// 'UIView' does not have a member named 'tableView'
如何告诉Swift我用MyViewController
子类覆盖view
的{{1}}属性?这甚至可能吗?如果没有,为什么不呢?
答案 0 :(得分:24)
我认为在Swift中可能无法实现完全相同的实现。从Swift书中有关覆盖属性的部分:
“您必须始终说明您的财产的名称和类型 覆盖,以使编译器检查您的覆盖 匹配具有相同名称和类型的超类属性。“
但是,您可以使用一个计算属性来返回视图控制器的view
属性的类型转换版本,它几乎一样干净:
class MyViewController: UIViewController, UITableViewDataSource {
var myView: MyView! { return self.view as MyView }
override func loadView() {
view = MyView(frame: UIScreen.mainScreen().bounds)
}
override func viewDidLoad() {
super.viewDidLoad()
self.myView.tableView.dataSource = self
}
}
答案 1 :(得分:0)
我们可以使用这样的东西吗?
class MyViewController: UIViewController, UIScrollViewDelegate {
weak var viewAlias: UIScrollView!
override func loadView() {
let scrollView = UIScrollView(frame: UIScreen.mainScreen().bounds)
viewAlias = scrollView
view = scrollView
}
override func viewDidLoad() {
//super.viewDidLoad()
viewAlias.delegate = self
viewAlias.contentSize = view.frame.size
// Do any additional setup after loading the view.
}
答案 2 :(得分:0)
[Apple Developer]这样做1:
以下显示了如何覆盖视图控制器 viewDidLoad()方法将其视图转换为SKView:
override func viewDidLoad() { super.viewDidLoad() view = SKView() } var skView: SKView { return view as! SKView }
或者,Xcode的新项目游戏模板就是这样做的:
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Can now set up view as if it were a SKView.
}
}