我开始在视图控制器上编写Swift扩展。所以我现在有三个文件:
我的标题文件ViewController.h
:
@interface MyViewController : UIViewController
@end
我的Obj-C实施文件ViewController.m
:
@interface MyViewController () <UIScrollViewDelegate>
@property (strong, nonatomic) UIScrollView *scrollView;
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc] init];
[self customiseScrollView]; //This is Swift method called from Obj-C file
}
@end
最后,ViewController.swift
:
extension MyViewController {
func customiseScrollView() {
}
}
我的问题是,是否可以从我的Swift实现文件中访问我的Obj-C属性?每次我提到它,我都会收到错误:
Value of type 'MyViewController' has no member 'scrollView'
奖金1:有人也可以澄清Swift组件是否能够看到.m是代表的内容。 (澄清一下,在Swift中执行scrollView.delegate = self
是一个编译错误,因为Swift文件没有意识到.m文件是一个UIScrollViewDelegate)。
Bonus 2:Swift扩展文件可以调用从.m对应文件声明的Obj-C方法吗?
答案 0 :(得分:5)
我认为(未经测试,我的XCode正处于更新过程中),您无法从扩展程序访问私有属性。您的scrollView属性位于.m文件中,而不是.h - 这意味着它是私有的,并且从扩展文件中看不到它。
解决方案:移动
@property (strong, nonatomic) UIScrollView *scrollView;
到你的头文件。
答案 1 :(得分:2)
如果在单独的标头中声明objc类扩展并将该标头包含在桥接标头中,则可以访问内部objc属性和方法。
MyClass.h
@interface MyClass : NSObject
@property (nonatomic, copy, readonly) NSString *string;
@end
MyClass + Private.h
#import "MyClass.h"
@interface MyClass ()
@property (nonatomic, copy) NSString *string;
@end
MyClass.m
#import "MyClass+private.h"
@implementation MyClass
//...
@end
Project-Bridging-Header.h
#import "MyClass.h"
#import "MyClass+Private.h"
答案 2 :(得分:1)
在Swift中,无法从其他文件访问私有属性。这就是Swift中private
的含义。例如:
<强> file1.swift 强>
class MyClass {
private var privateProperty: String = "Can't get to me from another file!"
}
extension MyClass: CustomStringConvertible {
var description: String {
return "I have a `var` that says: \(privateProperty)"
}
}
<强> file2.swift 强>
extension MyClass {
func cantGetToPrivateProperties() {
self.privateProperty // Value of type 'MyClass' has no memeber 'privateProperty'
}
}
在Objective-C类的实现中声明的属性是私有属性。因此,无法从Swift扩展访问该属性,因为这必须来自不同的(.swift
)文件...
答案 3 :(得分:-1)
你可以。您所需要的只是创建一个桥接目标C头。
要在与您相同的应用目标中导入一组Objective-C文件 Swift代码,你依靠Objective-C桥接头来暴露它们 文件到Swift。 Xcode提供在添加时创建此头文件 Swift文件到现有的Objective-C应用程序,或者Objective-C文件到 现有的Swift应用程序。
答案 4 :(得分:-1)
只需创建一个Bridging-Header文件,然后在其中导入ObjC文件,例如:
#import <objectivec.h>
稍后在你的swift文件中:
var a = objectivec()
a.method_from_those_file
有关详细信息,请参阅here中的Apple Doucmentation。