Search code examples
iosuitableviewswiftuianimation

Moving UITableView position in Swift


I am trying to animate a UITableView so that when the view appears, it slides up from the bottom of the screen. I have tried using loads of different methods from different questions on here, but no suggestions have worked for me.

What I have at the moment is this:

override func viewDidLoad() {
    super.viewDidLoad()

    menuTableView.layer.cornerRadius = 7

    menuTableView.delegate = self
    menuTableView.dataSource = self
    view.addSubview(menuTableView)

    menuTableView.frame.origin.y = menuTableView.frame.origin.y + menuTableView.frame.height
    // Do any additional setup after loading the view.
}

override func viewDidAppear(animated: Bool) {
    if (menuTableView.indexPathForSelectedRow() != nil) {
        menuTableView.deselectRowAtIndexPath(menuTableView.indexPathForSelectedRow()!, animated: true)
    }

    UIView.animateWithDuration(10, animations: {
        self.menuTableView.frame.origin.y - menuTableView.frame.height
    })
}

Someone suggested adding the UITableView as a subview, so I tried that, but it also doesn't work. The table just stays where it is.

Does anyone know a way that works in Swift?


Solution

  • You can try to change the table contentInset instead of changing the frame.

    override func viewDidLoad() {
        super.viewDidLoad()
    
        menuTableView.layer.cornerRadius = 7
    
        menuTableView.delegate = self
        menuTableView.dataSource = self
        view.addSubview(menuTableView)
    
        menuTableView.contentInset = UIEdgeInsets(top: self.view.bounds.height, left: 0, bottom: 0, right: 0)
    }
    
    override func viewDidAppear(animated: Bool) {
        if (menuTableView.indexPathForSelectedRow() != nil) {
            menuTableView.deselectRowAtIndexPath(menuTableView.indexPathForSelectedRow()!, animated: true)
        }
    
        UIView.animateWithDuration(10, animations: {
             self.menuTableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        })
    }
    

    So the table view always stays on top, only the top edge of table cells moves from bottom to the top.

    ========================================================================

    Edit

    I changed your code a little bit to make the background image move together.

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        var frame = self.menuTableView.frame
        frame.origin.y += menuTableView.frame.height
        self.menuTableView.frame = frame
    }
    
    override func viewDidAppear(animated: Bool) {
        if (menuTableView.indexPathForSelectedRow() != nil) {
            menuTableView.deselectRowAtIndexPath(menuTableView.indexPathForSelectedRow()!, animated: true)
        }
    
        UIView.animateWithDuration(10, animations: {
            var frame = self.menuTableView.frame
            frame.origin.y -= self.menuTableView.frame.height
            self.menuTableView.frame = frame
        })
    }
    

    1: Put your initial frame code in viewDidLayoutSubviews, if your want to change the frame after applying all the constraints.

    2: To be able to change frame, you needs to call the setter of frame attributes.

    someView.frame = someFrame
    

    Tell me if there're further problems.

    Edit

    Github link for a working demo: https://github.com/liusally/SlideUpMenuTableView