Làm thế nào để một người đi về làm một đại biểu, tức là NSUserNotificationCenterDelegate
trong nhanh chóng?
Làm thế nào để một người đi về làm một đại biểu, tức là NSUserNotificationCenterDelegate
trong nhanh chóng?
Câu trả lời:
Nó không khác với obj-c. Đầu tiên, bạn phải chỉ định giao thức trong khai báo lớp, như sau:
class MyClass: NSUserNotificationCenterDelegate
Việc thực hiện sẽ như sau:
// NSUserNotificationCenterDelegate implementation
func userNotificationCenter(center: NSUserNotificationCenter, didDeliverNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, didActivateNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
//implementation
return true
}
Tất nhiên, bạn phải thiết lập đại biểu. Ví dụ:
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
, cho phép bạn khởi tạo / cấu hình trình điều khiển khung nhìn, cũng như gọi các phương thức ủy nhiệm trong các cuộc phỏng vấn? Một cái gì đó tương tự như thế này ?
Dưới đây là một chút trợ giúp về các đại biểu giữa hai bộ điều khiển xem:
Bước 1: Tạo giao thức trong UIViewControll mà bạn sẽ xóa / sẽ gửi dữ liệu.
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
Bước2: Khai báo đại biểu trong lớp gửi (tức là UIViewcontroll)
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
Bước 3: Sử dụng ủy nhiệm trong một phương thức lớp để gửi dữ liệu đến phương thức nhận, đây là bất kỳ phương thức nào áp dụng giao thức.
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
Bước 4: Thông qua giao thức trong lớp nhận
class ViewController: UIViewController, FooTwoViewControllerDelegate {
Bước 5: Thực hiện phương thức đại biểu
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
Bước 6: Đặt đại biểu trong phần chuẩn bị:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! FooTwoViewController
vc.colorString = colorLabel.text
vc.delegate = self
}
}
Và điều đó nên làm việc. Tất nhiên đây chỉ là đoạn mã, nhưng sẽ cho bạn ý tưởng. Đối với một lời giải thích dài về mã này, bạn có thể đi đến mục blog của tôi ở đây:
Nếu bạn quan tâm đến những gì đang diễn ra dưới mui xe với một đại biểu tôi đã viết về điều đó ở đây:
weak
chỉ cần thiết cho các lớp không structs và enums. Nếu đại biểu sẽ là một cấu trúc hoặc enum thì bạn không cần phải lo lắng về các chu kỳ giữ lại. Tuy nhiên, ủy nhiệm một lớp của nó (điều này đúng với rất nhiều trường hợp vì khá thường xuyên là ViewContoder), sau đó bạn cần weak
nhưng bạn cần khai báo giao thức của mình là một lớp. Có thêm thông tin ở đây stackoverflow.com/a/34566876/296446
Các đại biểu luôn làm tôi bối rối cho đến khi tôi nhận ra rằng một đại biểu chỉ là một lớp làm một số việc cho một lớp khác . Giống như có người khác ở đó để làm tất cả công việc bẩn thỉu cho bạn mà bạn không muốn tự làm.
Tôi đã viết một câu chuyện nhỏ để minh họa điều này. Đọc nó trong Sân chơi nếu bạn thích.
// MARK: Background to the story
// A protocol is like a list of rules that need to be followed.
protocol OlderSiblingDelegate: class {
// The following command (ie, method) must be obeyed by any
// underling (ie, delegate) of the older sibling.
func getYourNiceOlderSiblingAGlassOfWater()
}
// MARK: Characters in the story
class BossyBigBrother {
// I can make whichever little sibling is around at
// the time be my delegate (ie, slave)
weak var delegate: OlderSiblingDelegate?
func tellSomebodyToGetMeSomeWater() {
// The delegate is optional because even though
// I'm thirsty, there might not be anyone nearby
// that I can boss around.
delegate?.getYourNiceOlderSiblingAGlassOfWater()
}
}
// Poor little sisters have to follow (or at least acknowledge)
// their older sibling's rules (ie, protocol)
class PoorLittleSister: OlderSiblingDelegate {
func getYourNiceOlderSiblingAGlassOfWater() {
// Little sis follows the letter of the law (ie, protocol),
// but no one said exactly how she had to respond.
print("Go get it yourself!")
}
}
// MARK: The Story
// Big bro is laying on the couch watching basketball on TV.
let bigBro = BossyBigBrother()
// He has a little sister named Sally.
let sally = PoorLittleSister()
// Sally walks into the room. How convenient! Now big bro
// has someone there to boss around.
bigBro.delegate = sally
// So he tells her to get him some water.
bigBro.tellSomebodyToGetMeSomeWater()
// Unfortunately no one lived happily ever after...
// The end.
Trong đánh giá, có ba phần chính để tạo và sử dụng mẫu đại biểu.
So với câu chuyện về Bossy Big Brother của chúng tôi ở trên, các đại biểu thường được sử dụng cho các ứng dụng thực tế sau:
Phần lớn là các lớp này không cần biết gì về nhau trước ngoại trừ lớp đại biểu tuân thủ giao thức được yêu cầu.
Tôi rất khuyên bạn nên đọc hai bài viết sau. Họ đã giúp tôi hiểu các đại biểu thậm chí còn tốt hơn các tài liệu đã làm.
Thêm một lưu ý
Các đại biểu tham chiếu các lớp khác mà họ không sở hữu nên sử dụng weak
từ khóa để tránh chu kỳ tham chiếu mạnh. Xem câu trả lời này để biết thêm chi tiết.
Tôi đã nhận được một vài chỉnh sửa đối với bài đăng của @MakeAppPie
Đầu tiên, khi bạn tạo giao thức ủy nhiệm, nó phải phù hợp với giao thức Class. Giống như trong ví dụ dưới đây.
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
Thứ hai, đại biểu của bạn nên yếu để tránh chu kỳ giữ lại.
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
Cuối cùng, bạn an toàn vì giao thức của bạn là một giá trị tùy chọn. Điều đó có nghĩa là tin nhắn "không" của nó sẽ không được gửi đến tài sản này. Nó tương tự như câu lệnh có điều kiện với respondToselector
trong objC nhưng ở đây bạn có mọi thứ trong một dòng:
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
Ở trên bạn có một ví dụ obj-C và bên dưới bạn có ví dụ Swift về giao diện của nó.
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
sẽ không gặp sự cố vì nếu đại biểu là nil
không có gì sẽ xảy ra. Tuy nhiên, nếu bạn mắc lỗi và viết delegate!.myMethod
bạn có thể gặp sự cố nếu một đại biểu không được thiết lập, vì vậy về cơ bản đó là cách để bạn an toàn ...
Đây là một ý chính tôi đặt lại với nhau. Tôi đã tự hỏi tương tự và điều này đã giúp cải thiện sự hiểu biết của tôi. Mở cái này lên trong Xcode Playground để xem chuyện gì đang xảy ra.
protocol YelpRequestDelegate {
func getYelpData() -> AnyObject
func processYelpData(data: NSData) -> NSData
}
class YelpAPI {
var delegate: YelpRequestDelegate?
func getData() {
println("data being retrieved...")
let data: AnyObject? = delegate?.getYelpData()
}
func processYelpData(data: NSData) {
println("data being processed...")
let data = delegate?.processYelpData(data)
}
}
class Controller: YelpRequestDelegate {
init() {
var yelpAPI = YelpAPI()
yelpAPI.delegate = self
yelpAPI.getData()
}
func getYelpData() -> AnyObject {
println("getYelpData called")
return NSData()
}
func processYelpData(data: NSData) -> NSData {
println("processYelpData called")
return NSData()
}
}
var controller = Controller()
UIViewController
lớp học của tôi để phù hợp với đại biểu chúng tôi đã thực hiện? Họ có phải được khai báo trong một tập tin nhanh không? Bất kỳ trợ giúp sẽ có rất nhiều ý nghĩa.
class ViewController : UIViewController NameOfDelegate
.
a.swift
theo câu trả lời của bạn ở trên, nó không xuất hiện b.swift
. Tôi không thể đến bất kỳ lớp nào ngoài tập tin nhanh chóng của mình. có khó khăn gì không?
GIAO HÀNG TẬN NƠI 2
Tôi đang giải thích với ví dụ về Đại biểu có hai viewControllers. Trong trường hợp này, Đối tượng SecondVC đang gửi dữ liệu trở lại Trình điều khiển Xem đầu tiên.
Lớp có Tuyên bố giao thức
protocol getDataDelegate {
func getDataFromAnotherVC(temp: String)
}
import UIKit
class SecondVC: UIViewController {
var delegateCustom : getDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func backToMainVC(sender: AnyObject) {
//calling method defined in first View Controller with Object
self.delegateCustom?.getDataFromAnotherVC("I am sending data from second controller to first view controller.Its my first delegate example. I am done with custom delegates.")
self.navigationController?.popViewControllerAnimated(true)
}
}
Trong việc tuân thủ Giao thức ViewControll đầu tiên được thực hiện tại đây:
class ViewController: UIViewController, getDataDelegate
Định nghĩa phương thức giao thức trong Trình điều khiển Chế độ xem Đầu tiên (ViewContoder)
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
Trong quá trình đẩy SecondVC từ Bộ điều khiển Chế độ xem Đầu tiên (ViewContoder)
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
Lớp học đầu tiên:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
Lớp thứ hai:
class ViewController: UIViewController, NetworkServiceDelegate {
let network = NetworkService()
override func viewDidLoad() {
super.viewDidLoad()
network.delegate = self
network.fetchDataFromURL("Success!")
}
func didCompleteRequest(result: String) {
print(result)
}
}
Type 'ViewController' does not conform to protocol 'NetworkServiceDelegate'
. Đó là ngày thứ 6 của tôi trên swift :)
Từng bước rất dễ dàng (100% làm việc và thử nghiệm)
Bước 1: Tạo phương thức trên trình điều khiển xem đầu tiên
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
Bước2: Đặt ủy nhiệm trong khi đẩy sang bộ điều khiển xem thứ hai
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
bước 3: thiết lập đại biểu như
lớp ViewContoder: UIViewControll, ProcessStatusDelegate {
bước 4: Tạo giao thức
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
bước 5: lấy một biến
var delegate:ProcessStatusDelegate?
Bước 6: Trong khi quay lại phương thức ủy quyền của trình điều khiển xem trước, vì vậy, lần đầu tiên trình điều khiển xem thông báo với dữ liệu
@IBAction func buttonActionBack(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: true)
self.navigationController?.popViewController(animated: true)
}
@IBAction func buttonProgress(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: false)
self.navigationController?.popViewController(animated: true)
}
Ví dụ đơn giản:
protocol Work: class {
func doSomething()
}
class Manager {
weak var delegate: Work?
func passAlong() {
delegate?.doSomething()
}
}
class Employee: Work {
func doSomething() {
print("Working on it")
}
}
let manager = Manager()
let developer = Employee()
manager.delegate = developer
manager.passAlong() // PRINTS: Working on it
Đại biểu là một mẫu thiết kế cho phép một đối tượng gửi tin nhắn đến đối tượng khác khi một sự kiện cụ thể xảy ra. Tưởng tượng một đối tượng A gọi một đối tượng B để thực hiện một hành động. Sau khi hành động hoàn tất, đối tượng A nên biết rằng B đã hoàn thành nhiệm vụ và thực hiện hành động cần thiết, điều này có thể đạt được với sự giúp đỡ của các đại biểu! Dưới đây là hướng dẫn thực hiện các đại biểu từng bước trong swift 3
Các giải pháp ở trên có vẻ hơi phức tạp và đồng thời tránh sử dụng lại cùng một giao thức trong các bộ điều khiển khác, đó là lý do tại sao tôi đi kèm với giải pháp được gõ mạnh hơn bằng cách sử dụng loại xóa chung.
@noreturn public func notImplemented(){
fatalError("not implemented yet")
}
public protocol DataChangedProtocol: class{
typealias DataType
func onChange(t:DataType)
}
class AbstractDataChangedWrapper<DataType> : DataChangedProtocol{
func onChange(t: DataType) {
notImplemented()
}
}
class AnyDataChangedWrapper<T: DataChangedProtocol> : AbstractDataChangedWrapper<T.DataType>{
var base: T
init(_ base: T ){
self.base = base
}
override func onChange(t: T.DataType) {
base.onChange(t)
}
}
class AnyDataChangedProtocol<DataType> : DataChangedProtocol{
var base: AbstractDataChangedWrapper<DataType>
init<S: DataChangedProtocol where S.DataType == DataType>(_ s: S){
self.base = AnyDataChangedWrapper(s)
}
func onChange(t: DataType) {
base.onChange(t)
}
}
class Source : DataChangedProtocol {
func onChange(data: String) {
print( "got new value \(data)" )
}
}
class Target {
var delegate: AnyDataChangedProtocol<String>?
func reportChange(data:String ){
delegate?.onChange(data)
}
}
var source = Source()
var target = Target()
target.delegate = AnyDataChangedProtocol(source)
target.reportChange("newValue")
đầu ra : có giá trị mới newValue
Tạo một đại biểu trên lớp cần gửi một số dữ liệu hoặc cung cấp một số chức năng cho các lớp khác
Giống
protocol GetGameStatus {
var score: score { get }
func getPlayerDetails()
}
Sau đó trong lớp sẽ xác nhận với đại biểu này
class SnakesAndLadders: GetGameStatus {
func getPlayerDetails() {
}
}