user3746428
user3746428

Reputation: 11175

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?

Upvotes: 1

Views: 11733

Answers (2)

Gurjinder Singh
Gurjinder Singh

Reputation: 10299

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!
  }
}

Upvotes: 0

Shali Liu
Shali Liu

Reputation: 1174

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

Upvotes: 3

Related Questions