Bagaimana cara membuat delegasi, yaitu NSUserNotificationCenterDelegate
dengan cepat?
Bagaimana cara membuat delegasi, yaitu NSUserNotificationCenterDelegate
dengan cepat?
Jawaban:
Ini tidak jauh berbeda dari obj-c. Pertama, Anda harus menentukan protokol dalam deklarasi kelas Anda, seperti yang berikut:
class MyClass: NSUserNotificationCenterDelegate
Implementasinya akan terlihat seperti berikut:
// 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
}
Tentu saja, Anda harus mengatur delegasi. Sebagai contoh:
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
, memungkinkan Anda untuk init / mengkonfigurasi viewcontroller, serta memanggil metode delegasi pada subviews? Sesuatu yang mirip dengan ini ?
Berikut sedikit bantuan pada delegasi antara dua pengontrol tampilan:
Langkah 1: Buat protokol di UIViewController yang akan Anda hapus / akan kirim datanya.
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
Langkah2: Deklarasikan delegasi di kelas pengiriman (yaitu UIViewcontroller)
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
Langkah 3: Gunakan delegasi dalam metode kelas untuk mengirim data ke metode penerima, yang merupakan metode apa pun yang mengadopsi protokol.
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
Langkah 4: Adopsi protokol di kelas penerima
class ViewController: UIViewController, FooTwoViewControllerDelegate {
Langkah 5: Terapkan metode delegasi
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
Langkah 6: Tetapkan delegasi di prepForSegue:
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
}
}
Dan itu seharusnya berhasil. Ini tentu saja hanya fragmen kode, tetapi harus memberi Anda ide. Untuk penjelasan panjang tentang kode ini, Anda dapat mengunjungi entri blog saya di sini:
Jika Anda tertarik pada apa yang terjadi di bawah tenda dengan seorang delegasi saya menulis tentang itu di sini:
weak
hanya diperlukan untuk kelas yang bukan struct dan enum. Jika delegasi akan menjadi struct atau enum maka Anda tidak perlu khawatir tentang mempertahankan siklus. Namun, mendelegasikan sebuah kelas (ini berlaku untuk banyak kasus karena cukup sering dengan ViewController), maka Anda perlu weak
tetapi Anda perlu mendeklarasikan protokol Anda sebagai sebuah kelas. Ada info lebih lanjut di sini stackoverflow.com/a/34566876/296446
Delegasi selalu membingungkan saya sampai saya menyadari bahwa seorang delegasi hanyalah sebuah kelas yang berfungsi untuk kelas lain . Ini seperti memiliki orang lain di sana untuk melakukan semua pekerjaan kotor untuk Anda yang tidak ingin Anda lakukan sendiri.
Saya menulis sedikit cerita untuk menggambarkan hal ini. Baca di Taman Bermain jika Anda suka.
// 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.
Dalam ulasan, ada tiga bagian utama untuk membuat dan menggunakan pola delegasi.
Dibandingkan dengan cerita Bossy Big Brother kami di atas, delegasi sering digunakan untuk aplikasi praktis berikut:
Bagian yang hebat adalah bahwa kelas-kelas ini tidak perlu tahu apa-apa tentang satu sama lain sebelumnya kecuali bahwa kelas delegasi sesuai dengan protokol yang diperlukan.
Saya sangat merekomendasikan membaca dua artikel berikut. Mereka membantu saya memahami delegasi bahkan lebih baik daripada dokumentasi .
Satu catatan lagi
Delegasi yang mereferensikan kelas lain yang tidak mereka miliki harus menggunakan weak
kata kunci untuk menghindari siklus referensi yang kuat. Lihat jawaban ini untuk lebih jelasnya.
Saya mendapat beberapa koreksi untuk dikirim ke @MakeAppPie
Pertama-tama ketika Anda membuat protokol delegasi, protokol tersebut harus sesuai dengan protokol Kelas. Seperti pada contoh di bawah ini.
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
Kedua, delegasi Anda harus lemah untuk menghindari siklus mempertahankan.
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
Terakhir, Anda aman karena protokol Anda adalah nilai opsional. Itu berarti pesan "nihil" tidak akan dikirim ke properti ini. Ini mirip dengan pernyataan kondisional dengan respondToselector
di objC tetapi di sini Anda memiliki semuanya dalam satu baris:
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
Di atas Anda memiliki contoh obj-C dan di bawah Anda memiliki contoh Swift tentang tampilannya.
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
tidak akan macet karena jika didelegasikan nil
maka tidak akan terjadi apa-apa. Namun jika Anda membuat kesalahan dan menulis delegate!.myMethod
Anda bisa crash jika delegasi tidak diatur, jadi pada dasarnya cara Anda aman ...
Inilah intisari yang saya kumpulkan. Saya bertanya-tanya sama dan ini membantu meningkatkan pemahaman saya. Buka ini di Playground Xcode untuk melihat apa yang terjadi.
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
kelas saya apa saja untuk menyesuaikan delegasi yang kami buat? Apakah mereka harus dinyatakan dalam satu file cepat? Bantuan apa pun akan sangat berarti.
class ViewController : UIViewController NameOfDelegate
.
a.swift
sesuai dengan jawaban Anda di atas, itu tidak muncul b.swift
. Saya tidak dapat mencapai kelas apa pun di luar file cepat saya. ada pemikiran?
DELEGASI DALAM SWIFT 2
Saya menjelaskan dengan contoh Delegasi dengan dua viewControllers. Dalam hal ini, SecondVC Object mengirim data kembali ke View Controller pertama.
Kelas dengan Deklarasi Protokol
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)
}
}
Dalam protokol ViewController First, penyesuaian dilakukan di sini:
class ViewController: UIViewController, getDataDelegate
Definisi metode protokol di First View Controller (ViewController)
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
Selama mendorong SecondVC dari First View Controller (ViewController)
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
Kelas utama:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
Kelas kedua:
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'
tlg sarankan. Ini adalah hari ke-6 saya dengan sigap :)
Langkah demi langkah yang sangat mudah (100% berfungsi dan diuji)
langkah1: Buat metode pada pengontrol tampilan pertama
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
step2: Tetapkan delegate sambil mendorong ke controller tampilan kedua
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
step3: atur suka delegasi
kelas ViewController: UIViewController, ProcessStatusDelegate {
step4: Buat protokol
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
langkah 5: ambil variabel
var delegate:ProcessStatusDelegate?
Langkah 6: Ketika kembali ke metode delegasi panggilan pengendali tampilan sebelumnya, maka pengendali tampilan pertama memberi tahu dengan data
@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)
}
Contoh sederhana:
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
Delegasi adalah pola desain yang memungkinkan satu objek untuk mengirim pesan ke objek lain ketika peristiwa tertentu terjadi. Bayangkan sebuah objek A memanggil objek B untuk melakukan suatu tindakan. Setelah tindakan selesai, objek A harus tahu bahwa B telah menyelesaikan tugas dan mengambil tindakan yang diperlukan, ini dapat dicapai dengan bantuan delegasi! Berikut ini adalah tutorial penerapan delegasi langkah demi langkah di cepat 3
Solusi di atas tampak sedikit digabungkan dan pada saat yang sama menghindari penggunaan kembali protokol yang sama di pengendali lain, itu sebabnya saya datang dengan solusi yang lebih kuat diketik menggunakan penghapusan tipe generik.
@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")
output : mendapat nilai baru newValue
Buat delegasi di kelas yang perlu mengirim beberapa data atau menyediakan fungsionalitas ke kelas lain
Suka
protocol GetGameStatus {
var score: score { get }
func getPlayerDetails()
}
Setelah itu di kelas yang akan mengkonfirmasi ke delegasi ini
class SnakesAndLadders: GetGameStatus {
func getPlayerDetails() {
}
}