tableView is moving up more than the defined value - uitableview

i have TabBar embedded tableViewController and in my Cell i have a textView and am trying to move up tableView when textView's editing begins this is how am doing this :
func textViewDidBeginEditing(textView: UITextView) {
if textView == descriptionTextView {
let indexPath: NSIndexPath = NSIndexPath(forRow: 4, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Middle , animated: true)
if textView.textColor == UIColor.lightGrayColor() {
textView.text = nil
textView.textColor = UIColor.blackColor()
}
}
}
its working fine but the scrolling is not smooth enough and its scrolling some points extra then coming down maybe this is happening because of tabBars's frame
and for that i tried to set the content inSet :
tableView.contentInset = (UIEdgeInsets(top: 0, left: 0, bottom: -30, right: 0))
but still having the same issue
see the value of contentOffSet.y from ScrollViewDidScroll when editing begins:
tableView is Moving : 236.5
tableView is Moving : 247.5
tableView is Moving : 254.0
tableView is Moving : 255.5
tableView is Moving : 190.0
tableView is Moving : 189.5
tableView is Moving : 189.0
tableView is Moving : 187.0
tableView is Moving : 185.0
tableView is Moving : 182.0
tableView is Moving : 178.5
tableView is Moving : 175.0
tableView is Moving : 171.0
tableView is Moving : 167.0
tableView is Moving : 163.0
tableView is Moving : 159.0
tableView is Moving : 155.0
tableView is Moving : 152.0
tableView is Moving : 149.0
tableView is Moving : 146.5
tableView is Moving : 144.5
tableView is Moving : 143.5
tableView is Moving : 143.0
above you can see that at first its going to 255.5 then coming down to 143.0
anybody knows how to fix this ?

func textViewShouldBeginEditing(textView: UITextView) -> Bool{
if textView == descriptionTextView {
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.tableView.frame.size.height - 190 )
let indexPath: NSIndexPath = NSIndexPath(forRow: 4, inSection: 0)
UIScrollView .beginAnimations("UP", context: nil)
UIScrollView .setAnimationDuration(0.3)
scrollView.contentOffset = CGPointMake(0, CGFloat(305
+ 70 * CGFloat(isiphone6())))
UIScrollView .commitAnimations()
}
please try this

Related

UITableViewCells animating at different rate than collapsing tableHeaderView

I am trying ot troubleshoot a tableView header (pink) that is animating a collapse. As the tableViewHeader height is shrinking the table view cells should pull up with the top of their tableView (orange). The beginning and end states are correct, but somehow the table view cells are animating up at a different rate. Something is clearly wrong here, I just can't seem to pinpoint what it is.
It appears to have something to do with the fact that I am using self sizing table view cells and tableView.rowHeight = UITableViewAutomaticDimension. If I use fixed height cells everything is fine.
Beginning State:
Middle State (Note cells already sliding under header):
Final State (Final state of layout is correct):
Here is the code that animates the collapse.
func collapseHeader() {
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseIn, animations: {
self.tableView.beginUpdates()
if let header = self.tableView.tableHeaderView as? TopicTableHeaderView {
header.setHeaderState(state: .collapsed)
}
self.sizeHeaderToFit()
self.view.layoutIfNeeded()
self.tableView.endUpdates()
}) { (bool) in
print("collapse completed")
}
}
func sizeHeaderToFit() {
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var frame = headerView.frame
frame.size.height = height
if headerView.frame.height != height {
headerView.frame = frame
tableView.tableHeaderView = headerView
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
}
}
}
And the problem was simply where I was calling self.tableView.beginUpdates(). I moved that to the line directly above self.tableView.endUpdates() and that solved the problem.

UITableView.visibleCells not capturing all visible cells

I'm trying to animate a table view cells on the initial load. The animation works fine for all the cells, except for the last one at the bottom of the table which refuses to animate.
This is because the UITableView.visibleCells does not return this cell at the end. (it returns cells 0-12, the last cell is at index 13 and is clearly visible)
Here is the code. Is there anything I can do to ensure all the cells get animated?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
let cells = tableView.visibleCells
let tableHeight: CGFloat = clubsTable.bounds.size.height
for i in cells {
let cell: UITableViewCell = i as UITableViewCell
cell.transform = CGAffineTransformMakeTranslation(0, tableHeight)
}
var index = 0
for a in cells {
let cell: UITableViewCell = a as UITableViewCell
UIView.animateWithDuration(1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
cell.transform = CGAffineTransformMakeTranslation(0, 0);
}, completion: { (complete) in
})
index += 1
}
}
That is because the height of your table is less than the height of 13 cells. Thus it animates 12 cells. What you can do is to make the table height bigger in 30px (or any px until it contains 13 cells), and after the animation is done, change the height of the tableView back to normal.
after you call let cells = tableView.visibleCells can't you just do something like
let indexPath = NSIndexPath(forRow: cells.count, inSection: 0)
cells.append(tableView.cellForRowAtIndexPath(indexPath))
Going off memory on those function signatures but you get the point.

How to show/hide UISearchBar by action in Swift?

I have a UITableView with a UISearchBar. I need to show/hide my searchBar, by user action (button pressing):
I tried to use this code:
if self.tableView.contentOffset.y == 0 {
self.tableView.contentOffset = CGPoint(x: 0.0, y: self.searchBar.frame.size.height)
}
from this question.
Actually I've tried all of those answers. All of them just scroll my UITableView, and each time I'm scrolling my UITableView - searchBar appears.
I tried to do something like this:
self.newsTableView.tableHeaderView = nil; //Hide
and
self.newsTableView.tableHeaderView = self.SearchBar; //Show
But UITableView doesn't want to return searchBar;
How can I resolve this problem?
I need to hide searchBar by action, not to scroll my UITableView (hide like searchBar.hidden = true) Actually, searchBar.hidden = true works, but there is a white space instead of searchBar.
Use UIView.animation for searchBar and tableView
When you start scroll table
Change position/alpha of search bar and height of tableView
UIView.animateWithDuration(1.0, animations: {
searchBar.alpha = 0.0
tableView.view.frame.height = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height)
}, completion: {
(value: Bool) in
//do nothing after animation
})
In Xcode 7.3 in the ViewController.swift file it worked properly for me
CategoryTableView.tableHeaderView = searchController.searchBar // show
CategoryTableView.tableHeaderView = nil // hide
searchController.active = false
hope this could solve your problem. call this at launch of tableview to hide the searchBar and when you scroll down it will appear
var newBounds: CGRect? = self.newsTableView.bounds
newBounds?.origin.y = 0
newBounds?.origin.y = newBounds!.origin.y + self.searchBar.bounds.size.height
and then set the new bound of the tableView

Place UITableViewCell beneath siblings

I'm trying to build a custom UITableView that acts in a similar way to the reminders app.
Instead of the top-most visible cell scrolling off the display, I want it to be covered by the next cell so the cells appear to stack on top of one another as you scroll.
Currently I am using:
override func scrollViewDidScroll(scrollView: UIScrollView) {
let topIndexPath: NSIndexPath = tableView.indexPathsForVisibleRows()?.first as! NSIndexPath
let topCell = tableView.cellForRowAtIndexPath(topIndexPath)
let frame = topCell!.frame
topCell!.frame = CGRectMake(frame.origin.x, scrollView.contentOffset.y, frame.size.width, frame.size.height)
}
But the top cell is always above the second cell - causing the second cell to scroll under it.
Also if I scroll quickly this seems to misplace all of my cells.
EDIT: Have fixed this. Answer posted below for future reference.
For anybody searching this in the future.
Simply loop through all the visible cells and set their z position to their row number (so each cell stacks above the previous one).
The if statement tells the top cell to remain at the contentOffset of the scrollview and for all other cells to assume their expected position. This stops the other cells being offset if you scroll too quickly.
override func scrollViewDidScroll(scrollView: UIScrollView) {
// Grab visible index paths
let indexPaths: Array = tableView.indexPathsForVisibleRows()!
var i = 0
for path in indexPaths {
let cell = tableView.cellForRowAtIndexPath(path as! NSIndexPath)
// set zPosition to row value (for stacking)
cell?.layer.zPosition = CGFloat(path.row)
// Check if top cell (first in indexPaths)
if (i == 0) {
let frame = cell!.frame
// keep top cell at the contentOffset of the scrollview (top of screen)
cell!.frame = CGRectMake(frame.origin.x,
scrollView.contentOffset.y,
frame.size.width,
frame.size.height)
} else {
// set cell's frame to expected value
cell!.frame = tableView.rectForRowAtIndexPath(path as! NSIndexPath)
}
i++
}
}

how to put messageCell at bottom of tableView? *Swift*

Chat set up. messagetableView bottom constraint attached to top of dockView. Unfortunately the tableView messageCell doesn't conform to the same constraint forced on the tableView. In my screenshot you can see the yellow tableView. It starts at the top of the superView and extends down to the top of the UIViewDock. The white messageCell does not follow the tableView. Obviously the messageCell is doing this because there are only 5 rows of messages so how do I make the white cell start at the bottom of the tableView like chat apps do?
Someone in another old thread said to use this Obj-C.
#property (nonatomic, assign) BOOL shouldScrollToLastRow;
- (void)viewDidLoad
{
[super viewDidLoad];
_shouldScrollToLastRow = YES;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Scroll table view to the last row
if (_shouldScrollToLastRow)
{
_shouldScrollToLastRow = NO;
[self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
}
}
Is this correct and how would I do it in Swift?
Make your messageCell the footer of the table view so it will always stick to the bottom of the table. You can add a view to the table in IB, and give it an IBOutlet (I call mine footer in the code below).
#IBOutlet weak var footer: UIView!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 44
tableView.tableFooterView = footer
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentSize.height), animated: false)
}
In the "Send" button's action method, you can do this to add a new row and keep the table scrolled to the bottom,
#IBAction func sendMessage(sender: UIButton) {
var message = messageField.text
messages.append(message)
let lastPath = NSIndexPath(forRow: messages.count - 1, inSection: 0)
tableView.beginUpdates()
tableView.insertRowsAtIndexPaths([lastPath], withRowAnimation: .Automatic)
tableView.contentSize = CGSize(width: tableView.contentSize.width, height: tableView.contentSize.height + tableView.rowHeight)
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentSize.height), animated: true)
tableView.endUpdates()
}

Resources