Bir temsilci nasıl yapılır, yani NSUserNotificationCenterDelegate
hızlı bir şekilde?
Bir temsilci nasıl yapılır, yani NSUserNotificationCenterDelegate
hızlı bir şekilde?
Yanıtlar:
Obj-c'den farklı değil. İlk olarak, protokolü sınıf bildiriminizde aşağıdaki gibi belirtmelisiniz:
class MyClass: NSUserNotificationCenterDelegate
Uygulama aşağıdaki gibi görünecektir:
// 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
}
Tabii ki, delegeyi ayarlamanız gerekiyor. Örneğin:
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
da görünüm denetleyicisini başlatmanıza / yapılandırmanıza ve alt görünümlerde delege yöntemlerini çağırmanıza izin verir mi? Benzer bir şey bu ?
İki görünüm denetleyicisi arasındaki delegelere biraz yardım:
Adım 1: UIViewController'da verileri kaldıracağınız / göndereceğiniz bir protokol yapın.
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
Adım 2: Gönderen sınıfta delege bildirin (yani UIViewcontroller)
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
Adım 3: Verileri, alıcı yöntemi, protokolü benimseyen herhangi bir yöntem göndermek için bir sınıf yönteminde kullanın.
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
Adım 4: Protokolü alıcı sınıfta benimseyin
class ViewController: UIViewController, FooTwoViewControllerDelegate {
5. Adım: Temsilci yöntemini uygulayın
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
Adım 6: Temsilciyi preparForSegue'e ayarlayın:
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
}
}
Ve bu işe yaramalı. Bu elbette sadece kod parçalarıdır, ancak size fikir vermelidir. Bu kodun uzun bir açıklaması için buradaki blog girişime gidebilirsiniz:
Bir temsilci ile kaputun altında neler olup bittiğini merak ediyorsanız, buraya yazdım:
weak
yalnızca yapılar ve numaralandırmalar için değil sınıflar için gereklidir. Delege bir yapı veya numaralandırma yapacaksa, döngüleri tutma konusunda endişelenmenize gerek yoktur. Ancak, temsilci bir sınıf (bu çoğu zaman bir ViewController beri birçok durumda geçerlidir), o zaman ihtiyacınız weak
ama protokol olarak bir sınıf olarak ilan etmek gerekir. Burada daha fazla bilgi var stackoverflow.com/a/34566876/296446
Delegeler, bir temsilci sadece başka bir sınıf için iş yapan bir sınıf olduğunu fark edene kadar beni her zaman karıştırdı . Sanki yapmak istemediğiniz tüm kirli işleri sizin için orada yapacak birine sahip olmak gibi.
Bunu açıklamak için küçük bir hikaye yazdım. İsterseniz bir Bahçesi içinde okuyun.
// 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.
İncelemede, delege desenini yapmak ve kullanmak için üç anahtar bölüm vardır.
Yukarıdaki Bossy Big Brother hikayemize kıyasla, delegeler genellikle aşağıdaki pratik uygulamalar için kullanılır:
Büyük kısmı, delege sınıfının gerekli protokole uyması dışında, bu sınıfların önceden birbirleri hakkında hiçbir şey bilmelerine gerek olmamasıdır.
Aşağıdaki iki makaleyi okumanızı tavsiye ederim. Delegeleri belgelere göre daha iyi anlamama yardımcı oldular .
Bir not daha
Sahip olmadıkları diğer sınıflara başvuran delegeler, weak
güçlü referans döngülerinden kaçınmak için anahtar kelimeyi kullanmalıdır . Daha fazla ayrıntı için bu cevaba bakınız.
@MakeAppPie yayınlamak için birkaç düzeltme aldım
Öncelikle temsilci protokolü oluştururken Sınıf protokolüne uyması gerekir. Aşağıdaki örnekte olduğu gibi.
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
İkincisi, koruma döngüsünü önlemek için temsilcinizin zayıf olması gerekir.
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
Son olarak, güvendesiniz çünkü protokolünüz isteğe bağlı bir değerdir. Bu, "nil" mesajının bu mülke gönderilmeyeceği anlamına gelir. respondToselector
ObjC'deki koşullu ifadeye benzer, ancak burada her şey tek bir satırda var:
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
Yukarıda obj-C örneğiniz var ve aşağıda Swift'in nasıl göründüğüne dair bir örneğiniz var.
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
çünkü temsilci ise nil
hiçbir şey olmaz. Eğer bir hata yaptı ve yazdı Ancak eğer delegate!.myMethod
sen olabilir bir temsilci, ayarlı değilse çökmesine tedbirli olmak için onun temelde bir yol ... öylesine
İşte bir araya getirdiğim bir öz . Aynı şeyi merak ediyordum ve bu da anlayışımı geliştirmeye yardımcı oldu. Neler olup bittiğini görmek için bunu bir Xcode Playground'da açın .
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
sınıfımı yaptığımız delege uyacak şekilde nasıl yapabilirim ? Bir hızlı dosyada bildirilmeleri gerekiyor mu? Herhangi bir yardım çok şey ifade edecektir.
class ViewController : UIViewController NameOfDelegate
.
a.swift
yukarıdaki cevabınıza göre bir delege sınıfı oluşturduğumda ortaya çıkmıyor b.swift
. Hızlı dosyam dışında hiçbir sınıfa ulaşamıyorum. herhangi bir zorluğu var mı?
SWIFT 2'DEKİ DELEGELER
Ben iki viewControllers ile Temsilci örneği ile açıklıyorum.Bu durumda, SecondVC Nesne ilk Görünüm Denetleyicisi'ne veri gönderiyor.
Protokol Bildirimli Sınıf
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)
}
}
İlk ViewController Protokolü'nde uygunluk burada yapılır:
class ViewController: UIViewController, getDataDelegate
İlk Görünüm Denetleyicisindeki (ViewController) protokol yöntemi tanımı
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
SecondVC'yi First View Controller'dan (ViewController) itme sırasında
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
Birinci sınıf:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
İkinci sınıf:
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'
plz önermek gösterir . Hızlı benim 6. gün :)
Adım adım çok kolay (% 100 çalışma ve test edilmiş)
Adım 1: İlk görünüm denetleyicisinde yöntem oluşturma
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
Adım 2: İkinci görünüm denetleyicisine basarken temsilci ayarlama
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
step3: temsilci gibi ayarla
sınıfı ViewController: UIViewController, ProcessStatusDelegate {
step4: Protokol oluştur
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
step5: bir değişken al
var delegate:ProcessStatusDelegate?
step6: Önceki görünüm denetleyicisine geri dönme delege yöntemini çağırın, böylece ilk görünüm denetleyicisi verileri bildir
@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)
}
Basit Örnek:
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
Temsilciler, belirli bir olay gerçekleştiğinde bir nesnenin başka bir nesneye mesaj göndermesine izin veren bir tasarım modelidir. A nesnesinin bir eylemi gerçekleştirmek için B nesnesini çağırdığını düşünün. Eylem tamamlandığında, A nesnesi B'nin görevi tamamladığını bilmeli ve gerekli eylemi gerçekleştirmelidir, bu delegelerin yardımıyla gerçekleştirilebilir! İşte hızlı bir şekilde adım adım delegeleri uygulayan bir öğretici
Yukarıdaki çözümler biraz bağlı görünüyordu ve aynı zamanda diğer kontrol cihazlarında aynı protokolü tekrar kullanmaktan kaçındı, bu yüzden genel tip silme kullanarak daha güçlü yazılan çözümle geldim.
@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")
çıktı : yeni değer var yeniDeğeri
Sınıfta, bazı veri göndermesi veya diğer sınıflara bazı işlevler sağlaması gereken bir temsilci oluşturun
Sevmek
protocol GetGameStatus {
var score: score { get }
func getPlayerDetails()
}
Bundan sonra sınıfta bu delege onaylayacak
class SnakesAndLadders: GetGameStatus {
func getPlayerDetails() {
}
}