将数据从父 ViewController 传递到子 VC,无需故事板 - Swift 5

Posted

技术标签:

【中文标题】将数据从父 ViewController 传递到子 VC,无需故事板 - Swift 5【英文标题】:Pass data from a Parent ViewController to Child VC without Storyboards - Swift 5 【发布时间】:2020-03-10 12:53:19 【问题描述】:

一旦我通过 Github API 的 UITextField 获取数据,我就找不到将数据传递给子 VC 的方法

protocol GithubManagerDelegate 
    func didUpdateGithub(_ githubManager: GithubManager, github: GithubModel)
    func didFailWithError(error: Error)


struct GithubManager 
    let profileUrl = "https://api.github.com/users"
    let clientId = // deleted this
    let secretId = // deleted this

    var delegate: GithubManagerDelegate?

    func fetchProfile(profileName: String) 
        let urlString = "\(profileUrl)/\(profileName)?client_id=\(clientId)&client_secret=\(secretId)"

        performRequest(with: urlString)
    


    func performRequest(with urlString: String) 
        if let url = URL(string: urlString) 
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url)  (data, response, error) in
                if error != nil 
                    self.delegate?.didFailWithError(error: error!)
                    return
                

                if let safeData = data 
                    if let github = self.parseJSON(safeData) 
                        self.delegate?.didUpdateGithub(self, github: github)
                        print(github)
                    
                
            
            task.resume()
        

    

    func parseJSON(_ githubData: Data) -> GithubModel? 
        let decoder = JSONDecoder()

        do 
            let decodeData = try decoder.decode(GithubData.self, from: githubData)
            let name = decodeData.name ?? "The user does not have a name"
            let login = decodeData.login ?? "No username by this name." // TODO: Change to give a alert
            let avatarUrl = decodeData.avatar_url
            let blog = decodeData.blog ?? "No Blog"
            let bio = decodeData.bio ?? "No Bio"
            let location = decodeData.location ?? "No location"
            let followers = decodeData.followers
            let following = decodeData.following


            let github = GithubModel(githubName: login, githubUser: name, githubAvatar: avatarUrl, githubBio: bio, githubLocation: location, githubBlog: blog, githubFollowers: followers, githubFollowing: following)

            return github

         catch 
            delegate?.didFailWithError(error: error)
            return nil
        
    

在 textFieldDidEndEditing 的父 VC 中,我获取输入文本并使用它从 GithubAPI 获取信息

if let username = searchTextField.text 
            DispatchQueue.main.async 
                self.githubManager.fetchProfile(profileName: username)
            
        

然后在我的子 VC 中,我使用 GithubManagerDelegate,我在哪里使用 DispatchQueue,用信息填充标签。但是信息是空的,因为一旦收到数据,我就无法将其传递给孩子。

func didUpdateGithub(_ githubManager: GithubManager, github: GithubModel) 
        DispatchQueue.main.async 
            self.usernameLabel.text = github.githubName
        
    

我从 ParentVC 到 ChildVC 的方式:

navigationController?.pushViewController(profileVC, animated: true)

希望我让自己清楚问题是什么......

【问题讨论】:

在profileVC中创建一个变量名,在推送profileVC之前设置好 【参考方案1】:

当您尝试在parent ViewController 和child ViewController 之间传递数据时,您应该将子节点添加到子节点而不是导航。

child 视图控制器中:var passingName: String?

举例

let child = #YourChildViewController insitiate it.
        self.addChild(child)
        child.passingName = passingName
        self.view.addSubview(child.view)
        child.didMove(toParent: self)

希望这个解决方案对你有帮助

【讨论】:

以上是关于将数据从父 ViewController 传递到子 VC,无需故事板 - Swift 5的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 - 将输入验证数据从父输入传递到子输入

Swift - 将数据从父视图控制器传递到子视图控制器

如果数据属性在 VueJs 中从父组件传递到子组件,则无法将其作为对象进行操作

如何将 Angular 5 中的点击数据从父组件传递到子组件?

通过 uinavigationcontroller 将变量从父视图传递到子视图

从 API 获取数据后立即将数据从父组件传递到子组件时出现问题。 (仅限功能组件)