Swift: programmatically enumerate outgoing segues from a UIVIewController

浪子不回头ぞ 提交于 2019-12-18 06:59:15

问题


I want to list the outgoing segues from a UIViewController, as described in Programmatically enumerate outgoing Segues for a UIViewController, but in Swift. (Swift 2, Xcode 7, iOS8+).

I can do

override func viewDidLoad() {
    super.viewDidLoad()
    let s = valueForKey("storyboardSegueTemplates")
    print("switchingVC: segues: \(s)") 
}

and that produces output like

switchingVC: segues: Optional((
    "<UIStoryboardPresentationSegueTemplate: 0x1754a130>",
    "<UIStoryboardPresentationSegueTemplate: 0x17534f60>",
    "<UIStoryboardPresentationSegueTemplate: 0x17534fc0>"
))

but I struggle to produce anything after that. I can't find any definition of the UIStoryboardPresentationSegueTemplate. How can I persuade Swift to tell me what's inside it? How can I find the segue identifier?

Thanks!


回答1:


this valueForKey("storyboardSegueTemplates") is UNDOCUMENTED property and UIStoryboardPresentationSegueTemplate is UNDOCUMENTED class. Beware of rejection from App Store if you are uploading application to App Store.

If you want to use this in your in-house projects, use as following

for template in (valueForKey("storyboardSegueTemplates") as? [AnyObject])! {
    if let identifier = template.valueForKey("identifier") as? String {
        print("identifier - " + identifier)
    }
    else {
        print("no identifier for \(template)")
    }
}

Found from https://github.com/JaviSoto/iOS9-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIStoryboardSegueTemplate.h




回答2:


As per Swift 4.2 and from https://stackoverflow.com/a/35060917/1058199. Thanks /johnykutty.

import UIKit

extension UIViewController {

     // Segue aids in Swift
     @objc func isValidSegue(_ segueId: String?) -> Bool {
        let filteredArray = (value(forKey: "storyboardSegueTemplates") as? NSArray)?.filtered(using: NSPredicate(format: "identifier = %@", segueId ?? ""))
        let isValid = (filteredArray?.count ?? 0) > 0
        return isValid
     }

     @objc func segues() -> Array<Any>? {
        let segues = self.value(forKey: "storyboardSegueTemplates")
        return segues as! Array<Any>?
     }

    @objc func segueNames() -> Array<AnyHashable> {
        var segueNames = Array<Any>()

        let filteredArray = (value(forKey: "storyboardSegueTemplates") as? NSArray)?.filtered(using: NSPredicate(format: "identifier != nil" ))

        for template in filteredArray! as [AnyObject] {
           if let identifier = (template.value(forKey: "identifier") as? String) {
               segueNames.append(identifier)
            }
            else {
                segueNames.append("no identifier for \(template)")
            }
        }

        return segueNames as! Array<AnyHashable>
    }
}

I know my use of predicates could be better, but Swift is such a PITA when dealing with iterating arrays. Please feel free to improve this.



来源:https://stackoverflow.com/questions/35060206/swift-programmatically-enumerate-outgoing-segues-from-a-uiviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!