NSUserNotificationCenterDelegate
신속한 대의원을 만드는 방법은 무엇입니까?
NSUserNotificationCenterDelegate
신속한 대의원을 만드는 방법은 무엇입니까?
답변:
obj-c와 다르지 않습니다. 먼저 다음과 같이 클래스 선언에 프로토콜을 지정해야합니다.
class MyClass: NSUserNotificationCenterDelegate
구현은 다음과 같습니다.
// 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
}
물론 델리게이트를 설정해야합니다. 예를 들면 다음과 같습니다.
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
하여 뷰 컨트롤러를 초기화 / 구성하고 하위 뷰에서 대리자 메서드를 호출 할 수 있습니까? 이것 과 비슷한 것 ?
다음은 두 개의 뷰 컨트롤러 사이의 델리게이트에 대한 약간의 도움말입니다.
1 단계 : UIViewController에서 데이터를 제거 / 전송할 프로토콜을 만듭니다.
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
2 단계 : 발신 클래스 (예 : UIViewcontroller)에서 델리게이트 선언
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
3 단계 : 클래스 메서드의 델리게이트를 사용하여 데이터를 수신 메서드 (프로토콜을 채택하는 모든 메서드)로 보냅니다.
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
4 단계 : 수신 클래스의 프로토콜 채택
class ViewController: UIViewController, FooTwoViewControllerDelegate {
5 단계 : 델리게이트 메소드 구현
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
6 단계 : PreparingForSegue에서 대리인을 설정합니다.
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
}
}
그리고 그것은 효과가 있습니다. 이것은 물론 코드 조각 일뿐이지만 아이디어를 제공해야합니다. 이 코드에 대한 자세한 설명은 내 블로그 항목으로 이동하십시오.
대의원과 함께하는 일에 관심이 있다면 여기에 썼습니다.
weak
구조체와 열거 형이 아닌 클래스에만 필요합니다. 대리인이 구조체 또는 열거 형이 될 경우 유지주기에 대해 걱정할 필요가 없습니다. 그러나 클래스를 위임하십시오 (ViewController이기 때문에 많은 경우에 해당됩니다). weak
하지만 프로토콜을 클래스로 선언해야합니다. 여기에 더 많은 정보가 있습니다 stackoverflow.com/a/34566876/296446
델리게이트는 다른 클래스를 위해 일하는 클래스 일 뿐이라는 것을 깨달을 때까지 항상 혼란 스러웠다 . 그것은 당신이 스스로하고 싶지 않은 더러운 일을하도록 다른 사람을 갖는 것과 같습니다.
나는 이것을 설명하기 위해 작은 이야기를 썼습니다. 원한다면 운동장에서 읽어보십시오.
// 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.
검토에서 델리게이트 패턴을 만들고 사용하기위한 세 가지 주요 부분이 있습니다.
위의 Bossy Big Brother 이야기와 비교하여 델리게이트는 종종 다음과 같은 실용적인 응용 프로그램에 사용됩니다.
가장 중요한 부분은 델리게이트 클래스가 필요한 프로토콜을 준수한다는 점을 제외하고는이 클래스들이 서로에 대해 아무것도 알 필요가 없다는 것입니다.
다음 두 기사를 읽는 것이 좋습니다. 그들은 문서 보다 델리게이트를 더 잘 이해하도록 도와주었습니다 .
하나 더 참고
소유하지 않은 다른 클래스를 참조하는 대리인은 weak
강력한 참조주기를 피하기 위해 키워드를 사용해야합니다 . 자세한 내용은 이 답변 을 참조하십시오.
@MakeAppPie의 게시물에 대한 수정 사항이 거의 없습니다.
먼저 위임 프로토콜을 만들 때 클래스 프로토콜을 준수해야합니다. 아래 예와 같이.
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
둘째, 유지주기를 피하려면 대리인이 약해야합니다.
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
마지막으로, 프로토콜은 선택적인 값이므로 안전합니다. 즉, "nil"메시지가이 속성으로 전송되지 않습니다. respondToselector
objC 에 있는 조건문 과 비슷하지만 여기에는 한 줄로 모든 것이 있습니다.
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
위에는 obj-C 예제가 있고 아래에는 Swift 예제가 있습니다.
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
하면 대리자가 nil
없으면 아무 일도 일어나지 않기 때문에 충돌 이 발생하지 않습니다. 그러나 당신이 실수하고 글 delegate!.myMethod
을 쓴 다면 델리게이트가 설정되어 있지 않으면 충돌 할 수 있으므로 기본적으로 안전 할 수있는 방법입니다.
여기 내가 정리 한 요점 이있다. 나는 똑같이 궁금했고 이것이 내 이해를 향상시키는 데 도움이되었습니다. Xcode Playground 에서 열어서 무슨 일이 일어나고 있는지 확인하십시오.
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
우리가 만든 대의원을 준수하기 위해 수업을 어떻게 만들 수 있습니까? 하나의 신속한 파일로 선언해야합니까? 도움이 필요합니다.
class ViewController : UIViewController NameOfDelegate
.
a.swift
위의 답변 에 따라 델리게이트 클래스를 만들면에 표시 되지 않습니다 b.swift
. 신속한 파일 이외의 다른 수업에 도달 할 수 없습니다. 어떤 어려움?
스위프트 2의 대표단
두 개의 viewController가있는 Delegate의 예를 설명하고 있습니다.이 경우 SecondVC Object는 데이터를 첫 번째 View Controller로 다시 보냅니다.
프로토콜 선언 클래스
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)
}
}
첫 번째 ViewController 프로토콜에서 준수는 다음과 같습니다.
class ViewController: UIViewController, getDataDelegate
First View Controller (ViewController)의 프로토콜 메소드 정의
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
First View Controller (ViewController)에서 SecondVC를 푸시하는 동안
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
최상위:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
이급:
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 제안을 보여줍니다 . 그것은 나의 빠른 여섯 번째 날이다 :)
매우 쉬운 단계별 작업 (100 % 작업 및 테스트)
1 단계 : 첫 번째보기 컨트롤러에서 메소드 작성
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
2 단계 : 두 번째 뷰 컨트롤러로 푸시하면서 델리게이트 설정
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
3 단계 : 대표를 다음과 같이 설정
ViewController 클래스 : UIViewController, ProcessStatusDelegate {
4 단계 : 프로토콜 생성
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
step5 : 변수를 가져 가라
var delegate:ProcessStatusDelegate?
6 단계 : 이전보기 컨트롤러 호출 위임 메소드로 돌아 가면서 첫 번째보기 컨트롤러가 데이터로 알립니다.
@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)
}
간단한 예 :
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
위의 솔루션은 약간 결합 된 것처럼 보였고 동시에 다른 컨트롤러에서 동일한 프로토콜을 재사용하지 마십시오. 따라서 일반적인 유형 삭제를 사용하여보다 강력한 유형의 솔루션을 제공합니다.
@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")
출력 : 새로운 값을 얻음 newValue