I have two table views that I use as input accessory views in my project. One is created programatically, and displays perfectly well. The second is a custom table view with custom cells made in storyboard and stored as a property of the view controller as a strong reference.
#property UITableView *firstTable; #property (strong, nonatomic) IBOutlet UITableView *secondTable;
They are both initiated in viewDidLoad as follows:
self.firstTable = [[UITableView alloc] initWithFrame:
CGRectMake(0, 0, self.view.bounds.size.width, 100) style:UITableViewStylePlain];
self.firstTable.delegate = self;
self.firstTable.dataSource = self;
self.firstTable.scrollEnabled = YES;
self.firstTable.rowHeight = 30;
self.firstTable.backgroundColor = [[SwagCommonFunctions alloc] colorWithHexString:#"f4ecea"];
self.secondTable.frame = CGRectMake(0, 0, self.view.bounds.size.width, 100);
They are set as input accessory views in another function
[textView setInputAccessoryView:self.firstTableView];
[textView reloadInputViews];
OR
[textView setInputAccessoryView:self.secondTableView];
[textView reloadInputViews];
firstTable works perfectly. secondTable is never loaded because frame height is zero at the time of cellForRowAtIndexPath. If the frame height is manually set at 100 (the width is full screen) with origin of (0,0) in numberOfRowsInSection, secondTable appears as expected with the correct data, but the frame obscures the entire keyboard instead of resting in the normal inputAccessoryView location.
How do I set the frame of secondTable to behave correctly?
self.secondTable.autoresizingMask = UIViewAutoresizingNone;
Related
If I use the following code to add a tableHeaderView to a table...
UILabel *label = [UILabel new];
label.translatesAutoresizingMaskIntoConstraints = NO;
label.text = #"Hello, world!";
self.tableView.tableHeaderView = label;
The result is that the content of the table is pushed down by the height of the label.
This is fine and is what I want.
However, when I use my own custom view (set up in code) which has its own subviews etc... then the content of the table is not pushed down and the header view overlaps onto the content.
I'm not using AutoLayout to place the subviews of my custom view because of the nature of the view it doesn't really work as an AutoLayout view.
The frame of my custom view is (0, 0, 0, 0) with the content of the header view being drawn outside its bounds.
I have implemented the - (CGSize)sizeThatFitsSize:(CGSize)size method of my custom view but that hasn't changed anything.
Is there something else I need to implement also?
Example
If I use the following code to put a label inside my custom view...
- (instancetype)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
UILabel *label = [UILabel new];
label.text = #"Hello, world!";
[label sizeToFit];
[self addSubview:label];
label.frame = CGRectMake(0, 0, CGRectGetWidth(label.bounds), CGRectGetHeight(label.bounds));
}
return self;
}
Then the label appears in the same place as before but the content is not pushed down.
The frame of the view when you set it as the table header view is the size that the table view allocates and maintains for the view.
So, you need to determine the required size for your header view and change it's frame before setting it.
The table view will not make and queries or size changes for you. Autoresizing rules do apply so if the table view frame changes the header view will be resized according to the rules you specify. This may lead to different issues.
I've put a ScrollView in storyboard.
Next, in the code I call
self.scroll.frame = CGRectMake(100, 0, 800, 900);
I suppose the scroll should change the position into (100, 0)
But somehow it still remains in the original position where was set in storyboard.
What am I missing ?
Yes it won't work for any view in autolayout system at all if added using storyboard or xib.
If you want to set frame initialise in your code.
#property (nonatomic,strong) UIScrollView *scrollView;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 568)];
If you want to set position in autolayout system you should consider updating the constraints of the view.
self.scrollViewWidthConstraint.constant += 20;
[self.scrollView updateConstraints];
I am developing iOS App.
I add UITextView(100px height) on top of UIWebView and would like to make them scroll simultaneously.
I am writing down the following code. However, when I scroll my screen, only UIWebView is scrolled and UITextView isn't.(UITextView is fixed!)
I hope that when I scroll up my screen, both UIWebView and UITextView go up, and vice versa.
Could you tell me how to solve?
#interface DetailViewController ()<UIWebViewDelegate>{
UITextView *recommendText;
}
#property (weak, nonatomic) IBOutlet UIWebView *detailPage;
- (void)viewWillAppear:(BOOL)animated{
[self headerMake];
}
-(void)headerMake{
recommendText = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 320,100)];
recommendText.layer.borderWidth = 2;
recommendText.text = #"hogehoge";
[self.detailPage addSubview:recommendText];
[[self.detailPage scrollView] setContentInset:UIEdgeInsetsMake(100, 0, 0, 0)];
}
A text view is a scroll view subclass, and web views have a scrollView property.
Listen to both scroll views content offset change (using scrollViewDidScroll:) and update the content offset of the other scroll view accordingly. This will give you the effect of scrolling the two at the same time.
self.textview.delegate = self;
self.webview.scrollView.delegate = self;
...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(scrollView == self.textview)
{
self.webview.scrollView.contentOffset = self.textview.contentOffset;
}
else
{
self.textview.contentOffset = self.webview.scrollView.contentOffset;
}
}
If i understand your question correctly you should embed them both is a scroll view and disable scrolling in the UIWebview and the UITextView. then they will scroll as one. Although you may have to dynamically set the sizes of the Textview and webview if they have different content they have to support.
I have a .xib file who have one view, one tab bar and other 3 scrollViews, when the user select a new tab bar item I execute this code:
//Views e Scrolls
IBOutlet UIView *myView;
IBOutlet UIScrollView *myScroll;
IBOutlet UIScrollView *myScroll2;
IBOutlet UIScrollView *myScroll3;
#property (nonatomic) UIScrollView *scroll;
-(void)tabBar:(UITabBar *)tabBar
didSelectItem:(UITabBarItem *)item{
NSArray *viewsToRemove = [myView subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
if(item.tag == 1){
self.title = #"scroll 1";
scroll = myScroll;
}
if(item.tag == 2){
self.title = #"scroll 2";
scroll = myScroll2;
}
if(item.tag == 3){
self.title = #"scroll 3";
scroll = myScroll3;
}
scroll.contentSize = scroll.frame.size;
scroll.frame = myView.frame;
scroll.scrollEnabled = YES;
[myView addSubview:scroll];
[myView setBackgroundColor:[UIColor clearColor]];
}
This code works great, but when I select one of the scrolls that had previously been removed from view, they lose their scrolling (which had not happened before), why this is happening and how to solve?
It's this line here:
scroll.contentSize = scroll.frame.size;
When your UIScrollView's contentSize matches its frame.size, it doesn't need to scroll (by definition). You need to figure out the actual size of its content and use that. You can at least demonstrate the correct functionality (even if it isn't with correct values) by doing this:
scroll.contentSize = CGSizeMake(scroll.frame.size.width*2, scroll.frame.size.height*2);
You'll have to find the real content size for yourself, though.
Assuming I understand your intention correct: Removing a scollview from it superview will also remove it from the responderchain. It cant no longer respond to touch event - thus wont scroll.
The question itself and your purpose of code is not very clear. You may try to explain further. And check this line -
scroll.contentSize = scroll.frame.size;
A UIScrollView whose contentSize <= frame.size, will not scroll. To make it scroll, contentSize should be bigger than frame.size
You should usually set the contentSize depending on the amount of content (subviews) for the scrollView.
In the next line you changed the frame.size, but I do not think that makes the frame size smaller than contentSize in your case.
I'm facing a problem with UITableView and it's property tableHeaderView.
I want to have the tableHeaderView to behave like UISearchBar, i.e. the content offset should be the of tableHeaderView.
Setting contentOffset, etc. didn't help when the table view wouldn't fill the view's frame.
Here's a screenshot of the current behavior:
(source: tubtub.de)
And how I'd like it to have:
(source: tubtub.de)
I'm inserting the headerView in viewDidLoad as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
}
Any help or hint is highly appreciated. Thanks!
EDIT: I made it working by utilizing UIScrollViewDelegate and subclassing UITableView. Check it out on the github repo provided.
You can use setContentOffset: by headerView height.
This contentOffset will only happen when you have enough number of data to be off by your headerView height. i.e) If tableView is not scrollable because you have only few data like one in your screenshot, the headerView is still visible. However if you have lots of number of data that can't not be displayed in the screen it will have contentOffset.
Try this with 20 rows. You will see what I mean.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
[self.tableView setContentOffset:CGPointMake(0, 44)];
With only 3 rows, this contentOffset won't work and it might be desired behavior in your case because you don't want to hide the searchBar when you have extra space to display.
I came up with implementing my own solution.
I utilize UIScrollViewDelegate and came up with a subclass of UITableView for calculating the contentSize dynamically.
Take a look at the github repo here.
I would double check the frame for the table itself. By setting the headerView's frame to start at 0,0, you are specifying that it should have its origin in the top left of the the view that is designated for the table.