繁体   English   中英

在另一个视图控制器中调用方法,但不是segue到它?

[英]Call method in another View Controller, but not segue to it?

我有一个标签应用程序。

选项卡A:下载按钮。

选项卡B:TableView

我想要做的是当点击A中的按钮时,我希望调用B中的下载功能。

现在,点击按钮后我有几个场景:

  • 留在A
  • 如果我现在点击B,我可以看到下载过程,或者如果完成,我可以看到那里的文件。

     +----------------+ +-----------------+ | | |downloaded files | | | +-----------------+ | +------------+ | | | | | download | | +-----------------+ | +------------+ | | | | | | | +-------+--------+ +--------+--------+ |now in | B | | A | now in | | A | | | | B | +-------+--------+ +--------+--------+ 

现在我在A中编写下载功能,并将所有文件保存在目录中,每当我点击选项卡B时, viewWillAppear函数都会从目录中加载下载的文件,但问题是我想显示下载过程以防万一文件很大。

任何建议和代码片段都表示赞赏。

使用Swift 3

在我提供解决方案之前,我会指出@Paulw11的评论,他是100%正确的。 正确的约定是将连接逻辑视图控制器中拉出来 视图控制器中唯一的代码是显示视图所需的代码。 连接到服务器并管理结果与在视图中实际显示结果数据无关。

如果您真的觉得有必要直接从另一个视图调用函数, 则不应该通过创建视图控制器的新实例来实现。 相反,你应该像这样得到现有的实例:

let app = UIApplication.shared.delegate! as! AppDelegate
    if let viewControllers = app.window?.rootViewController?.childViewControllers {
        viewControllers.forEach { vc in
            if let view = vc as? AnotherViewController {
                view.downloadIt()
            }
        }
    }

就个人而言,无论如何,我建议将这个逻辑从视图控制器中拉出来。 如果您试图保持最小化,或者这是您正在进行的唯一Web服务调用,您可以简单地执行以下操作:

添加一个新的Swift文件,其中包含协议和该协议的扩展:

protocol Downloadable : class { }

extension Downloadable {

    func downloadStuff() -> String {
       // Add your download logic here
       return "downloading"
    } 
}

然后,在任何视图中,您希望能够使用此下载功能,只需将协议添加到View Controller,如下所示:

class ViewController: UIViewController, Downloadable {}

然后,您可以非常轻松地获取下载的数据,如下所示:

@IBAction func handleDownloadTapped(_ sender: UIButton) {
    let result = downloadStuff()
    print(result)
}

再说一遍,你不应该养成这样做的习惯,因为如果你正在使用一些不同的api调用它会变得混乱。

最好的做法是创建一个包含Web服务的类,我个人喜欢objc.io方法。 你可以在这里找到一个教程。

https://talk.objc.io/episodes/S01E01-networking

基本上你会创建这样的服务

public typealias JSONDict = [String: AnyObject]

struct Resource<A> {
    let url: URL
    let parse: (NSData) -> A?
}

let url = URL(string: "https://url")!

let myResource = Resource<[JSONDict]>(url: url) { data in
    let json = try? JSONSerialization.jsonObject(with: data as Data, options: [])
    return json as? [JSONDict]
}

final class Connect {
    class func load<A>(resource: Resource<A>, completion: @escaping (A?) -> Void) {
        URLSession.shared.dataTask(with: resource.url) { (data, _, _ ) in

            if let data = data {
                completion(resource.parse(data as NSData))
            } else {
                completion(nil)
            }
            }.resume()
    }
}

你可以在任何需要的地方调用它:

Connect.load(resource: myResource) { result in
    // do stuff with result
}

我希望这对某人有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM