简体   繁体   中英

Change view by changing segmented control

I have a view UIViewController which contains two containers, one container embed to UIViewController and second to UITableViewController. UIViewController has a SegmentedControl with 3 segments. I would like to change the UITableViewController contents according to each segment. Which way is better to implement that?

Example of one of the table views: (I have two more for songs and artists)

class AlbumsSegmentView: UITableViewController{

    let qryAlbums = MPMediaQuery.albums()
    var allAlbums : [MPMediaItem] = []
    var contentView = UIViewController()


    var myMP = MPMusicPlayerController.systemMusicPlayer()

    override func viewDidLoad() {

        /* Background */
        tableView.backgroundColor = UIColor.clear
        tableView.separatorColor = UIColor.clear

        /*  Grouping list  */
        qryAlbums.groupingType = MPMediaGrouping.album
        allAlbums += MPMediaQuery.albums().items!

        self.clearsSelectionOnViewWillAppear = false
        self.view.isHidden=true
    }



    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell: CustomTableViewCellAlbum = CustomTableViewCellAlbum(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
        cell.imageView!.clipsToBounds = true


        /*  For Album list  */
         let currLoc = qryAlbums.collectionSections![indexPath.section].range.location
         let rowItem = qryAlbums.collections![indexPath.row + currLoc]


        //Main text is Album name
        cell.textLabel!.text = rowItem.items[0].albumTitle
        cell.textLabel!.font = UIFont(name: "HelveticaNeue-Thin", size: 22)
        cell.textLabel!.textColor = UIColor.white


        // Detail text is Album artist
        cell.detailTextLabel!.text = rowItem.items[0].albumArtist!
        cell.detailTextLabel!.font = UIFont(name: "HelveticaNeue-Thin", size:18)
        cell.detailTextLabel!.textColor = UIColor.white


        cell.backgroundColor = UIColor.clear

        let seperatorImageView = UIImageView.init(image: UIImage.init(named: "Separator.png"))
        seperatorImageView.frame = CGRect(x: 10, y: cell.contentView.frame.size.height+26, width: cell.contentView.frame.size.width, height: 3)
        cell.contentView.addSubview(seperatorImageView)

        // Or number of songs from the current album if you prefer
        //cell.detailTextLabel!.text = String(rowItem.items.count) + " songs"

        // Add the album artwork
        let artWork = rowItem.representativeItem?.artwork
        let tableImageSize = CGSize(width: 10, height: 10) //doesn't matter - gets resized below
        let cellImg: UIImageView = UIImageView(frame: CGRect(x:12,y:6,width:60,height:60))
        cellImg.image = artWork?.image(at: tableImageSize)
        cell.addSubview(cellImg)

        return cell
    }

    /*  For Songs list  */

    func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
        let sectionIndexTitles = qryAlbums.itemSections!.map { $0.title }
        return sectionIndexTitles
    }
    func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
        return index
    }
    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return (qryAlbums.itemSections![section].title)
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return allAlbums.count
        //return (qryAlbums.collections?.count)!;
        //return qryAlbums.collectionSections![section].range.length
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let currLoc = qryAlbums.collectionSections![indexPath.section].range.location
        myMP.setQueue(with: qryAlbums.collections![indexPath.row + currLoc])
        myMP.play()
    }

}

class CustomTableViewCellAlbum: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

    // Here you can customize the appearance of your cell
    override func layoutSubviews() {
        super.layoutSubviews()
        // Customize imageView like you need
        self.imageView?.frame = CGRect(x:12,y:6,width:60,height:60)
        self.imageView?.contentMode = UIViewContentMode.scaleAspectFit

        self.textLabel?.frame = CGRect(x:78, y:5, width:200, height:30)
        self.detailTextLabel?.frame = CGRect(x:78, y:35, width:200, height:30)

    }
}

Example of container:

class MyParentViewController: UIViewController {

    var buttonPanelViewController: PanelViewController!
    var tableViewController: TableViewController2!


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let tableViewController = segue.destination as? TableViewController {
            self.tableViewController = tableViewController
        }
        else if let buttonPanelViewController = segue.destination as? PanelViewController {
            self.buttonPanelViewController = buttonPanelViewController
        }
    }
}

class TableViewController: UITableViewController {}

class PanelViewController: UIViewController {}

Example of Storyboard view Picture example

UPD: The last thing I tried was to create 3 different UIViews above each other in MyParentViewController and attach them to different classes (Song, Artist, Album) and trying to hide one by one after switching the segments, but it didn't work. Maybe there is another and better way to implement this?

class MyParentViewController: UIViewController {

    var buttonPanelViewController: PanelViewController!


      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let artistViewController = segue.destination as? ArtistViewController {
            self.artistViewController = artistViewController
        }
        else if let buttonPanelViewController = segue.destination as? PanelViewController {
            self.buttonPanelViewController = buttonPanelViewController
        }
        else if let songViewController = segue.destination as? SongViewController { self.songViewController = songViewController
        }
        else let albumViewController = segue.destination as? AlbumViewController { self.albumViewController = albumViewController
         }
        }
    }



}

class TableViewController: UITableViewController {}

class PanelViewController: UIViewController {

    @IBOutlet public weak var segmentTest: UISegmentedControl!


    @IBAction func testAction(_ sender: UISegmentedControl) {

        if (segmentTest.selectedSegmentIndex == 0){
            BackTableVC().view.isHidden=false
            SongsSegmentView().view.isHidden = true
            AlbumsSegmentView().view.isHidden = true
            print("Hi")

        }else if (segmentTest.selectedSegmentIndex == 1){
            BackTableVC().view.isHidden = true
            SongsSegmentView().view.isHidden = false
            AlbumsSegmentView().view.isHidden = true
            print("Thank")
        }else{
            BackTableVC().view.isHidden = true
            SongsSegmentView().view.isHidden = true
            AlbumsSegmentView().view.isHidden = false
            print("You")
        }

    }

     }

class ArtistViewController: UIView{

} class SongViewController: UIView{

} class AlbumViewController: UIView{

}

The best way to solve this problem is to not change the table view for each segmented control, but to change the cell on each segmented control. register 3 cells for the table view controller, and once the segmented control value changes, call a delegate function to change which cell is dequeued and then update the table view with the new contents.

From the BackPanelVC, create an action from your segmented control to its class on value changed. In that action, call a delegate function with which control it has been switched to.

protocol SegmentControlChangeDelegate {
    func segmentedControlChangedValue(_ value: Int)
}

class PanelViewController: UIViewController {

@IBOutlet public weak var segmentTest: UISegmentedControl!
var delegate: SegmentControlChangeDelegate?


@IBAction func testAction(_ sender: UISegmentedControl) {
    delegate.segmentedControlChangedValue(value: sender.selectedSegmentIndex)
    self.performSegue(with: "identifier")
}

}

And in the tableviewcontroller conform to the delegate like so:

class AlbumsSegmentView: UITableViewController, SegmentControlChangeDelegate {
     func segmentedControlChangedValue(_ value: Int){
     // Change which cell is being displayed with some type of boolean or switch statement that will be recalled in cell.dequeue
     }
}

And make sure that you set the delegate to self in the tableviewcontroller

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destinationVC = segue.destination as? PanelViewController {
        destinationVC.delegate = self
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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