1

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?

Dennis
  • 2,119
  • 20
  • 29
user3746428
  • 11,047
  • 20
  • 81
  • 137
  • Is the table view made in the storyboard, and is auto layout turned on (it is if you haven't turned it off)? – rdelmar Apr 17 '15 at 15:38
  • It is, yes. And I've turned auto-layout off. With the below answer's first suggestion, it does work, but there seems to be a second background left over (I assume because I'm adding a second tableview as a subview?). – user3746428 Apr 17 '15 at 15:42
  • Instead of turning it off, learn to use auto layout. With it, you should make an IBOutlet to the constraint that you want to modify, and modify its constant value in code to do the animation. – rdelmar Apr 17 '15 at 15:44
  • I definitely plan to, but the app I am making is a WWDC scholarship submission, so now isn't really a great time to learn considering the time constraints. – user3746428 Apr 17 '15 at 15:45

2 Answers2

3

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

Shali Liu
  • 1,174
  • 13
  • 23
  • Thanks for the response. That seems to move all of the cells down, and animates them up, but it doesn't move the table's background. – user3746428 Apr 17 '15 at 15:16
  • The edit didn't help unfortunately. The table just seems to get stuck at the bottom of the view. I found a workaround for the first suggestion and it's not perfect, but it works fairly well. Thanks! – user3746428 Apr 17 '15 at 15:56
  • @user3746428 appended the link for a demo with the second approach, if it helps a bit. I guess the constraints you set for the table may be different – Shali Liu Apr 17 '15 at 16:22
0

You can move UITableView up or down by changing the contentOffset property. Like below.

var currentOffset : CGPoint?
let screenScaleFactor : CGFloat = UIScreen.main.bounds.size.width / 375.0 

func moveTableViewUp() {
DispatchQueue.main.async {
   self.currentOffset = self.tblView.contentOffset // saving current position of tableView
   let maxY = self.tblView.contentOffset.y
   let offset = CGPoint.init(x: 0, y: maxY+200.0*screenScaleFactor) // set moving up value
   self.tblView.setContentOffset(offset, animated: false)
 }
}

func moveTableViewToOriginalPosition() {
   DispatchQueue.main.async {
        self.tblView.contentOffset =  self.currentOffset!
  }
}
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58