Ios Swift:如何在没有故事板的情况下更新容器视图中的数据

Ios Swift:如何在没有故事板的情况下更新容器视图中的数据,ios,swift,uicontainerview,Ios,Swift,Uicontainerview,我的项目是在不使用故事板的情况下以编程方式创建的。这就像苹果音乐公司的miniPlayer,当点击tableView中的一行时,会更新miniPlayer(在containerView中)的数据 我看到一些故事板和segue的示例,如下面的代码:在父viewController中调用子viewController的方法,以使用协议和委托更新数据 但是我不使用故事板,那么prepare()的替代代码是什么呢 我的代码:在根视图控制器(UITabViewController)中添加容器视图。 我想在

我的项目是在不使用故事板的情况下以编程方式创建的。这就像苹果音乐公司的miniPlayer,当点击tableView中的一行时,会更新miniPlayer(在containerView中)的数据

我看到一些故事板和segue的示例,如下面的代码:在父viewController中调用子viewController的方法,以使用协议和委托更新数据

但是我不使用故事板,那么
prepare()
的替代代码是什么呢

我的代码:在根视图控制器(UITabViewController)中添加容器视图。 我想在单击parentView中的行时触发更新。 子视图中的更新方法。
解决这个问题的方法不止一种


第一种方法-无自定义委托:

protocol ContentDelegate {
    func configure(songs: [Song]?, at index: Int)
}
class MiniPlayerViewController: UIViewController, ContentDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // add UI elements, any other setup code
    }
    
}

extension MiniPlayerViewController {
    
    func configure(songs: [Song]?, at index: Int) {
        if let songs = songs {
            let song = songs[index % songs.count]
            songTitle.text = song.title
            thumbImage.image = song.artwork
        } else {
            // placeholder fake info
            songTitle.text = "你在终点等我"
            thumbImage.image = UIImage(named: "Wang Fei")
        }
    }

}
使用子类
UITabBarController
作为“中介”。给它一个func,例如:

func configure(songs: [Song]?, at index: Int) -> Void {
    miniPlayer.configure(songs: songs, at: index)
}
然后,在“选择歌曲”视图控制器(其中一个选项卡)中:


第二种方法-使用自定义委托:

protocol ContentDelegate {
    func configure(songs: [Song]?, at index: Int)
}
class MiniPlayerViewController: UIViewController, ContentDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // add UI elements, any other setup code
    }
    
}

extension MiniPlayerViewController {
    
    func configure(songs: [Song]?, at index: Int) {
        if let songs = songs {
            let song = songs[index % songs.count]
            songTitle.text = song.title
            thumbImage.image = song.artwork
        } else {
            // placeholder fake info
            songTitle.text = "你在终点等我"
            thumbImage.image = UIImage(named: "Wang Fei")
        }
    }

}
确保您的“迷你玩家”控制器符合学员的要求:

protocol ContentDelegate {
    func configure(songs: [Song]?, at index: Int)
}
class MiniPlayerViewController: UIViewController, ContentDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // add UI elements, any other setup code
    }
    
}

extension MiniPlayerViewController {
    
    func configure(songs: [Song]?, at index: Int) {
        if let songs = songs {
            let song = songs[index % songs.count]
            songTitle.text = song.title
            thumbImage.image = song.artwork
        } else {
            // placeholder fake info
            songTitle.text = "你在终点等我"
            thumbImage.image = UIImage(named: "Wang Fei")
        }
    }

}
为“选择歌曲”视图控制器(以及任何其他选项卡控制器)提供一个委托变量:

class SelectSongViewController: UIViewController {

    var delegate: ContentDelegate?

    // everything else
}
然后,在子类的
UITabBarController
中:

override func viewDidLoad() {
    super.viewDidLoad()

    configureContainer()

    if let vc = viewControllers?.first as? SelectSongViewController {
        vc.delegate = miniPlayer
    }
    
}
现在,您的“选择歌曲”视图控制器可以调用委托函数:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let tbc = self.tabBarController as? CustomTabBarController else {
        return
    }
    let index = indexPath.row
    delegate?.configure(songs: songs, at: index)
}

如果您没有使用故事板,我假设您已经编写了添加子视图控制器并将其视图添加到层次结构的代码?如果是这样的话,那就是你现在在
prepare()
@DonMag中所做的一切,是的,我已经做过了。我在层次结构顶部的
UITabBarController
上添加了一个containerView,并将子视图(miniPlayer)控制器添加到此容器中。但是我不能在
prepare()
中这样做,而是应该在
didSelectRowAt
中这样做。但是,我不知道如何获取现有的子vc。显示如何添加子视图控制器的代码在哪里?@DonMag,更新!好的-那么
configureContainer()
是子类
UITabBarController
中的一个func?太棒了!第一种方法是直截了当的,很有魅力。我知道棘手的部分是如何使用现有的
miniPlayer
实例,但我从来没有想过使用中间方法。第二种方法还不起作用,因为
SelectSongViewController
位于导航控制器下,所以我会像这样调用它
viewControllers?.first?.first as?选择SongViewController
,但它返回零。我认为这是因为我们还没有初始化那个子VC,所以无法在根视图中获得那个子锚点。现在是凌晨3点,我想稍后再做更多的检查,谢谢!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let tbc = self.tabBarController as? CustomTabBarController else {
        return
    }
    let index = indexPath.row
    delegate?.configure(songs: songs, at: index)
}