iOS開發之OC與swift開發混編教程,代理的相互呼叫,block的實現。OC呼叫Swift中的代理, OC呼叫Swift中的Block 閉包,swift 3.0
阿新 • • 發佈:2019-01-11
最新一些學妹問起,所以抽點時間來寫的,適合入門級別的swift 與 OC 混編 的程式猿。
本文章將從兩個方向分別介紹 OC 與 swift 混編
1. 第一個方向從 swift工程 中引入 oc類
1. 1 如何在swift的類中使用oc類
1.2 如何在swift中實現oc的代理方法
1.3 如何在swift中實現oc的Block回撥
2. 第二個方向從OC工程中引入swift類
2.1 如何在OC類中使用swift類
2.2 如何在OC中實現swift的代理方法
2.3 如何在OC中實現swift中類似Block回撥
下面是具體的實現過程:
1.1 如何在swift的類中使用oc類?
1. swift工程中引入OC類。 具體實現過程。
1.1 新建一個swift工程類。 取名 swiftOrOC
1.2 實現的功能為 : 從swift. viewController.swift 中 push到 OC語言 secondViewController 控制器
1.2.1 新建SecondViewController 類 。
1.2.2 建立橋接檔案。 (很重要)
一定要記得點選這個按鈕。
1.2.3 接下來工程目錄如下:
1.2.4 接下來就可以實現具體的跳轉功能了。
ViewController.swift中具體實現
import UIKit class ViewController: UIViewController { @IBOutlet weak var hintLabel: UILabel! //稍後用來顯示回撥 // push 到 oc controller @IBAction func pushAction(_ sender: AnyObject) { let secondVC = SecondViewController.init() self.navigationController?.pushViewController(secondVC, animated: true) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
1.2 如何在swift中實現oc的代理方法
1.2.1 首先在 SecondViewController.h 中宣告一個協議。具體程式碼
#import <UIKit/UIKit.h>
@protocol SecondDelegate <NSObject>
-(void)refreshHintLabel:(NSString *)hintString;
@end
@interface SecondViewController : UIViewController
@property (nonatomic,weak)id<SecondDelegate> secondDelegate;
@end
1.2.2 然後在SecondViewController.m中,通過一個UITextField,讓使用者輸入內容,當用戶點選返回的時候把輸入框中的內容返回給對應的代理。具體程式碼如下
#import "SecondViewController.h"
#import "UIViewController+BackButtonHandler.h"
@interface SecondViewController ()
{
UITextField *textField;
}
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"oc";
self.view.backgroundColor = [UIColor whiteColor];
textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
textField.placeholder = @"請輸入使用者名稱";
[self.view addSubview:textField];
[textField.layer setBorderColor:[UIColor blackColor].CGColor];
[textField.layer setBorderWidth:1.0];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
#pragma mark 返回上一頁回撥 ,將使用者輸入的使用者名稱傳回給 ViewController.swift
-(BOOL)navigationShouldPopOnBackButton{
if ([_secondDelegate respondsToSelector:@selector(refreshHintLabel:)]) {
[_secondDelegate refreshHintLabel: textField.text];
}
return YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
1.2.3 接下來就非常簡單了,讓ViewController.swift只需要成為SecondViewController的代理,然後遵循她的協議,就可以了。 具體程式碼如下。
1.2.3.1 遵循協議
1.2.3.2 成為代理,並實現協議方法,更改controller.swift中hintLabel的text。
// push 到 oc controller
@IBAction func pushAction(_ sender: AnyObject) {
let secondVC = SecondViewController.init()
secondVC.secondDelegate = self;
self.navigationController?.pushViewController(secondVC, animated: true)
}
// SecondViewControll的代理方法
func refreshHintLabel(_ hintString: String!) {
hintLabel.text = "secondView textView.text = " + hintString;
}
1.3 如何在swift中實現oc的Block回撥
1.3.1 具體過程與1.2小節一樣。 直接上程式碼。1.3.2 宣告block;
typedef void(^RefreshHintLabelBlock)(NSString *hintString);
@interface SecondViewController : UIViewController
@property (nonatomic, copy) RefreshHintLabelBlock hintBlock;
@end
1.3.3 block的回撥。 SecondViewController.m中
#pragma mark 返回上一頁回撥 ,將使用者輸入的使用者名稱傳回給 ViewController.swift
-(BOOL)navigationShouldPopOnBackButton{
if (_hintBlock) {
_hintBlock(textField.text);
}
return YES;
}
1.3.4 在swift類中呼叫 oc的block.
// push 到 oc controller
@IBAction func pushAction(_ sender: AnyObject) {
let secondVC = SecondViewController.init()
// secondVC.secondDelegate = self;
secondVC.hintBlock = {(t:String?)in
self.hintLabel.text = "secondView textView.text = " + t!
}
self.navigationController?.pushViewController(secondVC, animated: true)
}
2. OC工程中引入swift類。 具體實現過程。
耽誤了不少時間, 今天才開始寫oc工程中引入swift類。
demo地址:
2.1 如何在OC類中使用swift類
2.1.1 新建一個基於OC語言的工程 ,取名 OcOrSwiftTwo 2.1. 2 實現的功能為 : 從oc類 viewcontroller中, push 至 swift語言 SecondViewController ,然後SecondViewController可以通過代理或者swift閉包把值傳回viewcontroller. 2.1.3 當前檔案目錄看下圖: (第四個箭頭: 橋接檔案) 2.2 如何在OC中實現swift的代理與閉包Block方法 2.2.1 如何在oc中引入swift類。#import "工程名-swift.h"#import "OcOrSwiftTwo-swift.h"
2.2.2 在secondViewController.swift 中實現代理與閉包,程式碼如下:
注意: @objc(代理名) 才能在外部可見這個代理
import UIKit
import Foundation
// 必須加上@objc 代理才能在oc類中可見。
@objc(EditTextFieldDelegate)
protocol EditTextFieldDelegate:NSObjectProtocol {
func editTextField(_ str: String) -> Void
}
@objc(SecondViewController)
class SecondViewController: UIViewController {
var editorDelegate:EditTextFieldDelegate?
var textField:UITextField?
var addButton:UIButton?
var pushButton:UIButton?
typealias editorBlock = (_ t:String) -> Void
var myEidtorBlock:editorBlock?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
textField = UITextField.init(frame: CGRect.init(x: 50, y: 60, width: 200, height: 50))
textField?.placeholder = "輸入返回首頁的內容"
self.view.addSubview(textField!)
addButton = UIButton.init(type: .custom)
addButton?.setTitleColor(UIColor.black, for: .normal)
addButton?.setTitle("pop", for: .normal)
addButton?.frame = CGRect.init(x: 50, y: 150, width: 200, height: 50)
addButton?.layer.borderColor = UIColor.black.cgColor
addButton?.layer.borderWidth = 1.0
addButton?.addTarget(self, action: #selector(popAction), for: .touchUpInside)
self.view.addSubview(addButton!)
pushButton = UIButton.init(type: .custom)
pushButton?.setTitleColor(UIColor.black, for: .normal)
pushButton?.setTitle("push", for: .normal)
pushButton?.frame = CGRect.init(x: 50, y: 250, width: 200, height: 50)
pushButton?.layer.borderColor = UIColor.black.cgColor
pushButton?.layer.borderWidth = 1.0
pushButton?.addTarget(self, action: #selector(pushAction), for: .touchUpInside)
self.view.addSubview(pushButton!)
}
func popAction() -> Void {
if editorDelegate != nil {
editorDelegate?.editTextField((textField?.text)!)
}
if ((self.myEidtorBlock) != nil){
self.myEidtorBlock!((textField?.text!)!)
}
self.navigationController?.popViewController(animated: true)
}
func pushAction() -> Void {
let three = ThreeViewController.init()
self.navigationController?.pushViewController(three, animated: true)
}
2.2.3 在oc類中viewcontroller.m 檔案中實現SecondviewController.swift的相關代理與閉包(block). 程式碼如下:
#import "ViewController.h"
#import "OcOrSwiftTwo-swift.h"
@interface ViewController ()<EditTextFieldDelegate>
@property (nonatomic, strong) UITextField *showTextField;
@property (nonatomic, strong) UIButton *pushButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_showTextField = [[UITextField alloc]initWithFrame:CGRectMake(50, 100 , 200, 50)];
_showTextField.placeholder = @"swift傳回的文字內容";
_showTextField.adjustsFontSizeToFitWidth = YES;
_showTextField.enabled = NO;
[self.view addSubview:_showTextField];
_pushButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_pushButton.layer setBorderColor:[UIColor blackColor].CGColor];
[_pushButton.layer setBorderWidth:1.0];
[_pushButton setFrame:CGRectMake(50, 200, 200, 50)];
[_pushButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[_pushButton setTitle:@"push" forState:UIControlStateNormal];
[_pushButton addTarget:self action:@selector(pushAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_pushButton];
}
-(void)pushAction{
SecondViewController *second = [[SecondViewController alloc]init];
// second.editorDelegate = self;
/*
swift中的閉包回滴
*/
second.myEidtorBlock = ^(NSString *str) {
_showTextField.text = [NSString stringWithFormat:@"second傳回資訊: %@",str];
};
[self.navigationController pushViewController:second animated:YES];
}
#pragma mark swift中的代理
-(void)editTextField:(NSString *)str{
_showTextField.text = [NSString stringWithFormat:@"second傳回資訊: %@",str];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}