skip to Main Content

Hello what I have is a UITableViewController which displays various sliding out menu options. The idea I have is instead of the menu options to be displayed right below the navigation bar but rather include an image and have these items displayed below the image. I tried to anchor the UITable view to the bottom anchor of the image but it does not work.
Below are some images:
Image from the view Hierarchy

class MenuViewController: UITableViewController {
    
    public var delegate: MenuControllerDelagate?
    private let menuItems: [MenuOptions]
    let darkColour = UIColor(displayP3Red: 33/255.0, green: 33/255.0, blue: 33/255.0, alpha: 1)
    
    private let profileImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.isUserInteractionEnabled = true
        iv.image = #imageLiteral(resourceName: "venom-7")
        return iv
    }()
    
    init(with menuItems: [MenuOptions]) {
        self.menuItems = menuItems
        super.init(nibName: nil, bundle: nil)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(profileImageView)
        profileImageView.anchor(top: view.topAnchor)
        profileImageView.setDimensions(height: 130, width: 130)
        profileImageView.layer.cornerRadius = 130/2
        profileImageView.centerX(inView: view)
        tableView.backgroundColor = darkColour
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return menuItems.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.textColor = .white
        cell.textLabel?.text = menuItems[indexPath.row].rawValue
        cell.backgroundColor = darkColour
        cell.imageView?.image = UIImage(systemName: MenuOptions.allCases[indexPath.row].imageName)
        cell.imageView?.tintColor = .white
        return cell
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true )
        let selectedItem = menuItems[indexPath.row]
        delegate?.didSelectMenuItem(named: selectedItem)
    }
}

Any advice how I could properly anchor the list items to be below the image would be greatly appreciated!

2

Answers


  1. From what I understand, instead of using UITableviewController you should use a UIViewController and add a UITableView in it then set the constraints.

    class MenuViewController: UITableViewController
    

    Instead use

    class MenuViewController: UIViewController {
       private lazy var tableView: UITableView = {
    ...
    }
    }
    

    Set the constraints now and subview. I think that would solve the issue

    Login or Signup to reply.
  2. It seems like you’re using UITableViewController and it doesn’t explicitly add subviews as UIViewCroller. Your must conform ViewController to UIViewController.

    After that initialize your UITableView

    lazy var tableView: UITableView {
    let tableView = UITableView()
    tableView.translatesAutoresizingMaskIntoConstraints = false
    return tableView
    }
    

    and in viewDidLoad() write

    view.addSubview(tableView)
    

    then create a function

    func setupViews() {
       NSLayoutConstraint.activate([
                profileImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
                profileImageView.heightAnchor.constraint(equalToConstant: 100),
                profileImageView.widthAnchor.constraint(equalTo: profileImageView.heightAnchor, multiplier: 1.0),
                profileImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                
                tableView.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 20),
                tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
                tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
                tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
                
            ])
    }
    

    and call the setupViews() in viewDidLoad

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search