Anchor a UIButton to the bottom of a UITableViewController's view - ios

I have the following requirement. When a UITableViewController's view is displayed, there are a variable number of rows. Underneath the rows, a button should be displayed.
When the number of rows is small, the button should be anchored to the bottom of the view.
When the number of rows is larger, the delete button should be placed immediately after the last row.
In other words:
And not:
My best attempt at this so far has involved setting a tableFooterView and trying to update its height using the contentSize of the UITableView, but I am running into all sorts of problems. I might continue down this path and ask for some help, but first I want to know if anyone has alternative (better) solutions.
The result must play nicely with a double-sized status bar (during a call for example) and I am targeting iOS 6.0. I am not using interface builder.

One possible solution to achieve this effect might have to use two different solutions.
If the amount of rows means that the button will be off the screen then use the footerView like you have been doing.
If the amount of rows means that the button will not be off screen then
Add the button to the tableView
Implement - (void)scrollViewDidScroll:(UIScrollView *)scrollView and update the frame of the button to be offset from the bottom.
The offset from the bottom might follow some logic like this
yOffset = CGRectGetHeight(tableView.frame) - (CGRectGetHeight(button.frame) + somePadding)
yOffset += tableView.contentOffset.y
This would mean that the button still moves up and down with the scrolling but you don't have to mess with the footerView height

Keep both the table view and a button inside scroll view. Keep the button at the bottom of the scrollview. For proper scrolling to work you might want to set the scrollEnabled property of the scroll views. For more details on that check this up
Scrolling a UITableView inside a UIScrollView
EDIT:
yourView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin ;
Check the accepted answer for this question for more details on implimenting struts and springs using code:
UIView autoresizingMask - Interface Builder to Code - Programmatically create struts and springs - Swift or Objective-C

Related

Placing a button at the bottom of a collectionView

I'm trying to make a collectionView that shows 10 item at first, when scrolling to the bottom I want to have a button that clicking it will load more info, its something simple but the thing is that I'm not using storyboard and I did everything programmatically, so how it can be done?
UICollectionView is a subclass of UIScrollView. So you need to:
Add your button as subview of your UICollectionView
Set it's frame in the way you prefer (if you count your frames in code - just set it manually) based on .contentSize of you UICollectionView.
Set .contentInset.bottom property based on the height of your button/footer
You need to handle the case when .contentSize changes. If your button should be visible all the time, maybe better to set your button frame in viewDidLayoutSubviews() function
If you want to show/hide it in some cases, you can animate it using UIView.animate(withDuration:) by setting .contentInset.bottom in the block

Add tableview to scrollview and have scrollview keep growing in height as cells are added to tableview

I want to make a full screen scrollview with various views in it but also have a tableview in it.
The thing is, I don't want the tableview to "reuse" views.
I am using auto-layout.
People keep asking why. Here is why:
I want the scrollview to keep growing in height as cells are added to the tableview. (using storyboard) This is something I want to do. Stop "suggesting" a "better" way because I know the "better" way. I am asking for this way.
For example:
As cells are added to the tableview, the entire scrollview keeps growing.
Hope you are using autolayout, considering this i guess you already added constraint from the bottom of tableview to the uiview below it and also add a height constraint to the tableview. Make a IBOutlet of this height constraint. now write a method that would calculate the height depending on number of items you have to show for the tableview like
func calculateTableViewHeight() {
heightConstraint.constant = YOUR_CELL_HEIGHT * NO_OF_ROWS
}
Call this method after tableview.reloadData(). And also don't for get to set the scrolling for the tableview to false

How to create up/down swipeable UITableView?

I have a UITableView in the bottom of UIViewController and tableview height is 100 point now.
The tableview has 20 cells and tableview's header view is 100 point. And I've added a up UISwipeGestureRecognizer and a down UISwipeGestureRecognizer in table view header.
Now I want to change the tableview height constraint constant to 400 in up gesture action and change the tableview height constraint constant to 100 in down gesture action.
Now the problem is gesture recognizer isnt working in tableview
header when tableview scroll is enabled.
If tableview scroll is disabled then the gesture recognizer is
working. But unable to view all cells once the tableview height is
changed.
Here's a different approach. Don't use swipe gesture recognizers at all.
Instead, make the table always the full 400 points tall. Set its contentInset.top to 300. This will allow the table view to scroll so that only its top 100 points of content are visible at the bottom of the screen. Specifically, the table view will allow its contentOffset.y (which is its vertical scrolling position) to go down to -300 (instead of only down to 0). The table's content always starts at y = 0, so when the table's contentOffset.y is -300, only the top 100 points of its content are visible. As the contentOffset.y increases, more of its content becomes visible.
Then, override the table view's point(inside:withEvent:) method to return true only for points with y >= 0. This means the table will ignore (pass through) touches above its content when its content is scrolled so only the top 100 points are visible.
This is the final effect for a small table:
or for a big table:
You can find a detailed explanation (in Objective-C) and a link to the full test project (also in Objective-C) in this answer.
As it may help others, here is the simplest possible solution to this type of problem.
Extremely simple solution -
no tricks, nothing fancy -
don't have a "table view header".
Just make a new UIViewController
class TableWithRedTop: UIViewController
that has ...
[ red area .. swipe detection ]
[ main area - the table view]
Then simply put 'TableWithRedTop' inside a container view.
(Container view tutorial if you need one.)
In your MainView just have a call
func toggleTableHeight
When 'TableWithRedTop' gets a swipe, have one line of code to call toggleTableHeight in MainView
Note that in toggleTableHeight you can easily animate the height change, tilt it on an angle, duplicate it or do anything you want, as you're using a container view in MainView.
I'm going to make another suggestion that may solve the issue for you.
It could be what you want is an:
"self-expanding" table...
First implement the following with no animations, for simplicity.
You have two heights for the table, small and large.
Start the table on height small.
Remarkably, you only have to implement these two rules: just two simple lines of code:
Any time the user is scrolling upwards - in fact, change to "height large".
Any time the user is scrolling downwards, and, you are at the top position of the table (i.e. you can see cell #1) in fact change to "height small".
It's one of those things that is "so simple, it's hard to believe it works!"
It's sometimes referred to as a "pull-up table" I think.
(Note. If you're not familiar with detecting when the user is scrolling, fortunately it is trivial - code shown here for example.)
Set both swipe gesture’s cancelsTouchesInView to true and make sure that the gestures are added directly to the header and not the tableView.
That should do the trick, but so should adding a view with the gesture recognizes to the container view and setting it’s constraints to match the tableView’s top, left, and right constraints and setting its height to 100.

Anchor a view at the bottom of a UITableViewController

I'm building a view which is a UITableView, however I want to anchor a "Write a comment" UITextField at the bottom of the screen. You can see an example of this on these screenshots from the "Secret" app - the "Write a comment (anonymously)" and "Post" button are anchored to the bottom of the screen regardless of whether you scroll the tableview items up or down.
What's the best way to achieve this?
Should I be embedding a UITableViewController into a UIViewController with the UIView anchored to the bottom of the screen and the tableview anchored to the top of this view?
Is this some kind of UITableView section footer?
Any advice greatly appreciated.
You could subclass UITableView and add a bottom view (not to confuse with a tableview's footerView). Since a UITableView is a subclass of UIScrollView, you can change its contentInsets so that the content of the tableview will still scroll above your bottom view.
tableView.contentInsets = UIEdgeInsetsMake(0, 0, 0, bottomViewHeight);
The next step would be to make the bottom view sticky, that is, floating with the bottom of the tableview. You can achieve this in multiple ways. Here are two suggestions:
1) Manipulating the frame directly
By conforming to UITableViewDelegate you automatically conform to UIScrollViewDelegate. You can see this by inspecting the protocol declaration in UITableView.h:
#protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
Then implement scrollViewDidScroll:(UIScrollView *)scrollView and change the y-offset of the bottomview to always position it at the bottom of the view. UIScrollView's contentOffset property is used to determine how far down the scrollview has scrolled. This method will be called every single time the scrollview scrolls, hence it will appear that the bottom view sticks to the bottom of the tableview.
2) Use auto layout
While still changing the contentInsets as above, you can achieve the sticky effect by using auto layout constraints instead. By pinning the bottom view to the edge of the scrollview, it will automatically create the sticky effect for you. This is by far my recommended approach, since it saves lines of code, while it uses the highest possible level of abstraction.
I use this category by Florian Kugler when implementing auto layout in code.
This technical note, however not strictly related to the issue, describes how to use auto layout with scrollviews.
I have in-app chat (like whatsapp) and I have the following structure:
UIViewController
\
- View
\
- UITableView
- UIView (with textfied)
I thinks this is the best approach as you don't mix table data with anything else, and you don't have to juggle with sections in code
if you requirement is to show only one picture related information at once in screen means please follow the process it will help you.
first take a view controller then take an image view and on it the buttons you needed add them on image view only below image view take a tableview(if there are comments show tableview. if no comments available show a label as"be first to comment").
Hope this will help

how to stop UITextView to scroll UITableView

I have a custom table with just three cells. In third cell I have a textView. The three cells cover up enough space on the screen so that just the keyboard space is left. I don't want anything to be movable or scrollable, so I used self.tableView.scrollEnabled = NO;.
This is working fine with earlier version of iOS. However with iOS 5, it shows some weird behavior. When I enter multiple lines of text in textView the whole table scrolls up. Ideally the table should stick there and only textView should scroll.
After trying lots of things I found that the textView is placed so near to the keyboard (as the textView is placed in last cell and just below it is the keyboard) that the iOS tries to move the textView up, for which it scrolls the complete table up. Is there any way to stop this auto scroll of tableView.
I found the same problem mentioned here
Disable UITextView scrolling the containing view?
however it is also not answered yet. And the workaround mentioned over there won't work for me as my containing view itself is scrollable (UITableView)
for me, i work around with scroll in table view like this
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(self.tableView.contentOffset.y != 0)
{
self.tableView.contentOffset = CGPointMake(0, 0);
}
}
One solution is to add a completely new subview on the fly. Add a UITextView to self.view and give it a frame that corresponds to the same position on the screen. The table view should not scroll now.
In case this does not work because self.view is the table view, change your controller into a class UIViewController and implement the delegate and datasource methods yourself (i.e. you have to mention them in the #interface declaration). The table view should then be a subview of self.view and you have to hook it up via IB.
Before you dismiss the keyboard, copy the content to your original text view.

Resources