문제

매우 간단한 질문일 수 있지만 검색해도 결과가 나오지 않아서 여기에 있습니다...

호출하기 전에 특정 뷰 컨트롤러가 식별자 XYZ를 사용하여 segue를 수행할 수 있는지 확인하는 방법을 찾으려고 합니다. performSegueWithIdentifier: 방법.

다음과 같은 내용이 있습니다.

if ([self canPerformSegueWithIdentifier:@"SegueID"])
    [self performSegueWithIdentifier:@"SegueID"];

가능한?

도움이 되었습니까?

해결책

문서에 명시된 바와 같이:

앱은 일반적으로 segue를 직접 트리거할 필요가 없습니다.대신, View Hierarchy에 내장 된 컨트롤과 같은 View Controller와 관련된 인터페이스 빌더에서 객체를 구성하여 Segue를 트리거합니다.그러나이 메소드를 호출하여 스토리 보드 리소스 파일에 지정할 수없는 일부 작업에 응답하여 프로그래밍 방식으로 트리거 할 수 있습니다.예를 들어, 쉐이크 또는 가속도계 이벤트를 처리하는 데 사용되는 사용자 정의 작업 핸들러에서 호출 할 수 있습니다.

이 메시지를 수신 한 뷰 컨트롤러는 스토리 보드에서로드되어야합니다.View Controller에 관련 스토리 보드가없는 경우, 아마도 직접 할당하고 초기화했기 때문에이 방법은 예외를 던집니다.

즉, segue, 일반적으로 이는 다음과 같이 가정되기 때문입니다. UIViewController 구체적인 답변으로 대응할 수 있을 것입니다. segue's 식별자.나도 Dan F의 의견에 동의합니다. 예외가 발생할 수 있는 상황을 피하려고 노력해야 합니다.다음과 같은 일을 할 수 없는 이유는 다음과 같습니다.

if ([self canPerformSegueWithIdentifier:@"SegueID"])
    [self performSegueWithIdentifier:@"SegueID"];

나는 다음과 같이 추측한다:

  1. respondsToSelector: 런타임에 해당 메시지를 처리할 수 있는지만 확인합니다.이 경우에는 수업이 가능하기 때문에 가능합니다. UIViewController 에 대응할 수 있다 performSegueWithIdentifier:sender:.메소드가 특정 매개변수를 사용하여 메시지를 처리할 수 있는지 실제로 확인하려면 불가능할 것 같습니다. 가능한지 확인하려면 실제로 메소드를 실행해야 하고 그렇게 할 때 NSInvalidArgumentException 오를 것이다.
  2. 제안한 내용을 실제로 작성하려면 해당 segue의 ID 목록을 받는 것이 도움이 될 것입니다. UIViewController 와 연관되어 있습니다.로부터 UIViewController 선적 서류 비치, 그렇게 보이는 항목을 찾을 수 없습니다.

지금으로서는 계속해서 이 방식을 유지하는 것이 최선의 방법이라고 생각합니다. @try @catch @finally.

다른 팁

SEGUE가 존재했는지 여부를 확인하려면 TRY-CATCH 블록으로 통화를 단순히 둘러 쌉니다.아래의 코드 예제를 참조하십시오 :

@try {
    [self performSegueWithIdentifier:[dictionary valueForKey:@"segue"] sender:self];
}
@catch (NSException *exception) {
    NSLog(@"Segue not found: %@", exception);
}
.

희망이 도움이됩니다.

- (BOOL)canPerformSegueWithIdentifier:(NSString *)identifier
{
    NSArray *segueTemplates = [self valueForKey:@"storyboardSegueTemplates"];
    NSArray *filteredArray = [segueTemplates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"identifier = %@", identifier]];
    return filteredArray.count>0;
}
.

이 게시물은 SWIFT 4에 업데이트되었습니다.


여기에 세그 척자가 존재하는지 확인하는 보다 올바른 스위프트 방법이 있습니다.

extension UIViewController {
func canPerformSegue(withIdentifier id: String) -> Bool {
        guard let segues = self.value(forKey: "storyboardSegueTemplates") as? [NSObject] else { return false }
        return segues.first { $0.value(forKey: "identifier") as? String == id } != nil
    }

    /// Performs segue with passed identifier, if self can perform it.
    func performSegueIfPossible(id: String?, sender: AnyObject? = nil) {
        guard let id = id, canPerformSegue(withIdentifier: id) else { return }
        self.performSegue(withIdentifier: id, sender: sender)
    }
}

// 1
if canPerformSegue("test") {
    performSegueIfPossible(id: "test") // or with sender: , sender: ...)
}

// 2
performSegueIfPossible(id: "test") // or with sender: , sender: ...)
.

- (BOOL) SUMETERPERFORMSEWHITEDIDERIDER : SENDER : 방법 및 논리를 수행 할 수 있습니다.

- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if ([identifier isEqualToString:@"someSegue"]) {
        if (!canIPerformSegue) {
            return NO;
        }
    }
    return YES;    
}
.

희망이 도움이됩니다.

참조 canperformsegue.swift

import UIKit

extension UIViewController{
    func canPerformSegue(identifier: String) -> Bool {
        guard let identifiers = value(forKey: "storyboardSegueTemplates") as? [NSObject] else {
            return false
        }
        let canPerform = identifiers.contains { (object) -> Bool in
            if let id = object.value(forKey: "_identifier") as? String {
                return id == identifier
            }else{
                return false
            }
        }
        return canPerform
    }
}
.

나에게 일한 Evgeny Mikhaylov의 답변의 신속한 버전 :

두 개의보기를 위해 컨트롤러를 재사용합니다.이렇게하면 코드를 재사용 할 수 있습니다.

if(canPerformSegueWithIdentifier("segueFoo")) {
  self.performSegueWithIdentifier("segueFoo", sender: nil)
}
else {
  self.performSegueWithIdentifier("segueBar", sender: nil)
}


func canPerformSegueWithIdentifier(identifier: NSString) -> Bool {
    let templates:NSArray = self.valueForKey("storyboardSegueTemplates") as! NSArray
    let predicate:NSPredicate = NSPredicate(format: "identifier=%@", identifier)

    let filteredtemplates = templates.filteredArrayUsingPredicate(predicate)
    return (filteredtemplates.count>0)
}
.

표준 함수를 사용하여 할 수있는 방법은 없습니다. 할 수있는 작업은 Subclass UIStoryboardSegue를 사용하고 생성자에게 전달 된 source View 컨트롤러 (생성자에 전달)에 정보를 저장합니다.인터페이스 빌더에서 Segue 유형을 Segue의 클래스 이름으로 "사용자 정의"를 선택하면 모든 세그리가 인스턴스화 된 모든 세그리 티드에 대해 생성자가 호출되고 저장된 데이터가 존재할 경우 쿼리 할 수 있습니다.

또한 perform 메소드를 무시하여 원하는 전환 유형에 따라 [source presentModalViewController:destination animated:YES] 또는 [source pushViewController:destination animated:YES]를 호출해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top