18

I started writing Swift extensions on my view controllers. So I have three files right now:

My header file, ViewController.h:

@interface MyViewController : UIViewController

@end

My Obj-C implementation file, 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

And finally, ViewController.swift:

extension MyViewController {

    func customiseScrollView() {

    }
}

My question is, is it possible to access my Obj-C properties from my Swift implementation file? Every time I refer to it, I got an error:

Value of type 'MyViewController' has no member 'scrollView'

Bonus 1: Can someone also clarify if the Swift component can see what the .m is a delegate of as well. (To clarify, doing scrollView.delegate = self in Swift is a compile error because the Swift file does not realise that the .m file is a UIScrollViewDelegate).

Bonus 2: Can Swift extension file call Obj-C methods that are declared from the .m counterpart?

4

5 回答 5

14

我认为您无法从扩展访问私有属性。您的 scrollView 属性在 .m 文件中,而不是 .h - 这意味着它是私有的,并且在扩展文件中不可见。

解决方案:移动

@property (strong, nonatomic) UIScrollView *scrollView;

到你的头文件。

于 2015-10-22T07:56:17.257 回答
6

如果在单独的标头中声明 objc 类扩展并将该标头包含在桥接头中,则可以访问内部 objc 属性和方法。

我的类.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

我的班级.m

#import "MyClass+private.h"

@implementation MyClass

//...

@end

项目-桥接-Header.h

#import "MyClass.h"
#import "MyClass+Private.h"
于 2018-12-26T15:43:12.577 回答
1

在 Swift 中,不能从另一个文件访问私有属性。这就是privateSwift 中的含义。例如:

文件 1.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)"
    }
}

文件2.swift

extension MyClass {
    func cantGetToPrivateProperties() {
        self.privateProperty // Value of type 'MyClass' has no memeber 'privateProperty'
    }
}

在 Objective-C 类的实现中声明的属性是私有属性。因此,无法从 Swift 扩展访问该属性,因为这必然来自不同的 ( .swift) 文件...

于 2015-10-22T08:13:10.227 回答
-1

你可以。您所需要的只是创建一个桥接目标 C 标头。

根据Apple 文档

要在与您的 Swift 代码相同的应用程序目标中导入一组 Objective-C 文件,您需要依赖 Objective-C 桥接头将这些文件公开给 Swift。当您将 Swift 文件添加到现有的 Objective-C 应用程序或将 Objective-C 文件添加到现有的 Swift 应用程序时,Xcode 会提供创建此头文件的功能。

于 2015-10-22T07:51:49.723 回答
-1

只需创建一个 Bridging-Header 文件,然后在其中导入您的 ObjC 文件,例如:

#import <objectivec.h>

稍后在您的 swift 文件中:

var a = objectivec()
a.method_from_those_file

欲了解更多信息,请从此处阅读 Apple 文档。

于 2015-10-22T07:51:50.050 回答