i am new in Google admob development. In this case i need to add an admob inside my uitableview, I make an implementation like this on :
the problem is, the cell that contain the ads (I Use DFPBannerView) is scrollable, i want to make it unscrollable. I just want to make the uitableview scrollable but the banner view is not. I already implement some suggestion from UIScrollView doesn't scroll when touching GADBannerView subview
but it still can not make the ads unscrollable. is there anyone can help me?
There are basic 2 solutions to this:
Add the view to the superview of your table view instead of to the table view itself. Then you just set the frame of the tableview to be shorter so that it is not cut off by the banner. This is provided you are not using a UITableViewController because if you're using one of those, the table view is the root view.
Add the subview to your tableview directly, and implement scrollViewDidScroll: and change its frame based on that. The implementation would look something like this:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect bannerFrame = myBanner.frame;
bannerFrame.origin.y = CGRectGetMaxY(scrollView.bounds) - bannerFrame.size.height;
myBanner.frame = bannerFrame;
}
I am trying to have some controls (labels, inputs) and TableView in ScrollView (I have table at bottom). So when user is scrolling that first there are hidden controls at top and then are shown items at their place and then first items are hidden and next are shown etc.
I created this code:
if(self.searchResultsTableView.frame.size.height != self.searchResultsTableView.contentSize.height)
{
CGRect newFrame = self.searchResultsTableView.frame;
newFrame.size = self.searchResultsTableView.contentSize;
self.searchResultsTableView.frame = newFrame;
mainScrollView.contentSize = CGSizeMake(320, self.searchResultsTableView.frame.origin.y + newFrame.size.height);
}
in this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Height is calculated right and it's working but I have problem with some cells. It shows just cell which are loaded and visible without scrolling and when I am trying to scroll I am scrolling but next cells aren't visible. I must tap a few times on button to reload cells to get them visible and then I see them and everything works.
I guess this could be problem because some lazy loading or something like that. Anyone can help me? Thanks
Try this
set your tableview scrolling disable
and set your scrollview content size as your table height.
Try use willDisplayCell instead cellForRow.
I am creating an app and in one of the navigation views, I have a very similar design as that of the App Store app — see Details | Reviews | Related section. Following on similar lines, I wish to implement the segmented control in the 'same' way Apple has done in their app. (This is also similar to what Apple does in the Artist -> Albums navigation view in the default iOS 7 music app, albeit for a table header (maybe).)
If you scroll up, when the segmented control container touches the navigation bar, it sticks there.
It also allows the user to notice that this is some kind of overlay due to the alpha associated with it.
When you scroll down, it moves into position when required.
What I have done —
I have created a container view with the segmented control. When the scrollView scrolls, I reposition my container view to accomplish the sticky effect. This is just pseudo-code but my code actually works.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == self.labTestScrollView)
{
/*
As soon as the user scrolls up, y changes, therefore, we need to stick the options container view
such that it doesn't go past the UINavigationBar
Need to check if the origin of the options container view in the coordinate system of the main
superview is just gone past the UINavigationBar in this controller's view.
- get the bounds rect for the options container view
- convert these bounds and position them in the coordinates of this controller's view
- check if origin.x for container view is less than that of view.origin.y
- if less than stick it by converting the headerFrame to the coordinate system of the options
container view; and raise the stuck flag
- if greater, check if the stuck flag is raised; check for another object in space before the container view and adjust accordingly.
*/
}
}
There are two issues:
No overlay effect. I can configure the alpha such that the effect is a bit more visible but that doesn't seem natural.
The second concern stems from the first. This seems like a very specific solution. I am looking forward to something that's more natural; and something that could work by default using table views or something.
Why not simply use a UITableView?
Put your 'top content' in section 0 and have no header for that section. Put all the other stuff in section 1 and give that section a header with your UISegmentedControl.
Following code works pretty well. You might want to find a way to give the background of the header a 'blur' effect to mimic Apple's behavior some more; maybe GPUimage could help you there?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return section == 0 ? 1 : 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = indexPath.section == 0 ? #"header" : #"content";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// customize cell
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if(section == 1) {
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"Foo", #"Bar"]];
segmentedControl.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.95];
return segmentedControl;
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 0 : 44;
}
I'll leave the tweaking up to you ;)
This is actually 2 views.
The first is the header of a UITableView.
This includes the segmented control and the app icon, the install button, etc...
The second view has a segmented control that sits at the top of the screen and is hidden.
When the tableview scrolls you can intercept the scroll view delegate method scrollView:didScroll...
In here, if the scrollView offset is larger than the height of the header then make the second view visible. Else make it hidden.
That's it. Now you just need to remember to update both segmented controls whenever one is hanged.
I have a UIScrollView which contains a UIView and a UITableView. My goal is to adjust the height of the UIScrollView to allow me to scroll the contents of the UIScrollView to a specific point.
Here is my view: It has a UIView up top and a UITableView down below.
When I scroll, I want the UIView to stop at a specific point like so:
The tableView would be able to continue scrolling, but the UIView would be locked in place until the user scrolled up and brought the UIView back to its original state.
A prime example of what I am trying to do is the AppStore.app on iOS 6. When you view the details of the app, the filter bar for Details, Reviews and Related moves to the top of the screen and stops. I hope this all made sense.
Thanks
I ended up going with a simpler approach. can't believe I didn't see this before. I created two views, one for the UITableView's tableHeaderView and one for the viewForHeaderInSection. The view I wanted to remain visible at all times is placed in the viewForHeaderInSection method and the other view is placed in the tableHeaderView property. This is a much simpler approach, I think than using a scrollview. The only issue I have run into with this approach is all my UIView animations in these two views no longer animate.
Here is my code.
[self.tableView setTableHeaderView:self.headerView];
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return self.tableViewHeader;
}
add yourself as a UIScrollViewDelegate to the UITableView and implement the - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView so that if your views are in their starter positions they do this:
- your UITableView animates its size to the second state:
[UIView animateWithDuration:.1f animations:^{
CGRect theFrame = myView.frame;
theFrame.size.height += floatOfIncreasedHeight;
myView.frame = theFrame;
}];
- your UIView animates its vertical movement
[UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(void){
view.center = CGPointMake(view.center.x , view.center.y + floatOfVerticalMovement);
}completion:^(BOOL Finished){
view.center = CGPointMake(view.center.x , view.center.y - floatOfVerticalMovement);]
Finally always in the delegate implement – scrollViewDidScrollToTop: so that you know can animate back to the initial state (using the same techniques reversed).
UPDATE:
since your views are inside a scroll view, there is a simpler way if you are ok with the table view being partly out of bounds in your starter position (i.e. instead of changing size it just scrolls into view):
make the scroll view frame size as big as your final tableview + your initial (entire) view and place it at 0,0 (so its final part will be hidden outside of the screen)
scrollview.frame = CGRectMake(0,0,tableview.frame.size.width,tableview.frame.size.height + view.frame.size.height);
you make the container scrollview contents as big as the entire table view + the entire view + the amount of the view that you want out of the way when scrolling the table view.
scrollview.contentSize = CGSizeMake(scrollview.frame.size.width, tableview.frame.size.height + view.frame.size.height + floatOfViewHeightIWantOutOfTheWay);
you place the view one after the other in the scrollview leaving all the additional empty space after the table view
view.frame = CGRectMake(0,0,view.frame.size.width, view.frame.size.height);
tableview.frame = CGRectMake(0,view.frame.size.height, tableview.frame.size.width, tableview.frame.size.height);
now it should just work because since iOS 3 nested scrolling is supported
You can easily achieve this by setting the content size of the scrollView correctly and keep the height of the UITableView smaller than your viewcontroller's height, so that it fits the bottom part of the top UIView and the UITableView...
Another scenario is to split the top View in 2 parts.
The part that will scroll away and the part that will be visible.
Then set the part that will scroll away as the entire UITableView header and the part that will remain visible as the header view for the first table section.
So then you can achieve this with a single UITableView, without having to use a UIScrollView
What you're looking for is something like what Game Center happens to do with it's header which can actually be modelled with a table header, a custom section header view, and some very clever calculations that never actually involve messing with the frame and bounds of the table.
First, the easy part: faking a sticky view. That "view that's always present when scrolling the table" implemented as a section header. By making the number of sections in the table 1, and implementing -headerViewForSection:, it's possible to seamlessly make the view scroll with the tableview all for free (API-wise that is):
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,320,50)];
label.text = #"Info that was always present when scrolling the UITableView";
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor colorWithRed:0.243 green:0.250 blue:0.253 alpha:1.000];
label.textColor = UIColor.whiteColor;
return label;
}
Finally, the hard part: KVO. When the table scrolls, we have to keep the header up there sticky with regards to the top of the view's frame, which means that you can KVO contentOffset, and use the resultant change in value to approximate the frame that the view should stick to with a little MIN() magic. Assuming your header is 44 pixels tall, the code below calculates the appropriate frame value:
CGPoint offset = [contentOffsetChange CGPointValue];
[self.tableView layoutSubviews];
self.tableView.tableHeaderView.frame = CGRectMake(0,MIN(0,offset.y),CGRectGetWidth(self.scrollView.frame),44);
If the above is infeasible, SMHeadedList actually has a fairly great, and little known, example of how complicated it can be to implement a "double tableview". That implementation has the added benefit of allowing the "header" tableview to scroll with the "main" tableview.
For future visitors, I've implemented a much simpler version, albeit one that accomplishes the goal with Reactive Cocoa, and a little bit of a different outcome. Even so, I believe it may be relevant.
What if you break the UIView into the top and bottom. The bottom will be the info.
Set UITableView.tableHeaderView = topView in viewDidLoad
and the return bottomView as Section Header in delegate method to make it float:
(UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section
{
return bottomView;
}
Just using the UITableView can solve with your problem. it is not need to use another scroll view.
set your view as the header view of UITableView. Then add your present view to the header view.
complete - (void)scrollViewDidScroll:(UIScrollView *)scrollView; . Tn the function to check the contentoffset of scroll view, and set the present view's frame.
I currently have a view controller that is comprised of a Navigation bar, followed by a UIView that has two UIButtons added as subViews. There is then a UITableView underneath that begins at the bottom of the container UIView.
At the moment, when the user scrolls the UITableView it goes behind the UIView and UIButtons. What I actually want to happen is for the UIView and UIButtons to move up with the table view but only by the value of their height which in this case is 58 pixels. The flow would be like this...
1) Table scrolls and the UIView moves with it for the first 58 pixels.
2) The user continues to scroll the table but the UIView "pins" itself just out of view under the navigation bar.
3) When the user scrolls the table back down the UIView is then picked up and dragged back into view. I believe the new Facebook app does something similar in the timeline.
I don't want to set the UIView as the TableHeaderView of the table as I also have a pull-to-refresh which then sits above the buttons and looks terrible. I've tried playing around with the contentOffset properties of the underlying scrollview of the table but have hit a brick wall.
Any advice on where to start would be appreciated.
Thanks
EDIT: I am gotten a little further and using this code to move the frame of the UIView.
-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog (#"Content Offset: %f", self.tableView.contentOffset.y);
NSLog (#"Button Frame: %f", self.btnBackground.frame.origin.y);
if (self.tableView.contentOffset.y > 0)
{
CGRect newFrame = self.btnBackground.frame;
newFrame.origin.x = 0;
newFrame.origin.y = -self.tableView.contentOffset.y;
[self.btnBackground setFrame: newFrame];
}
}
The problem now is that the scrollViewDidScroll delegate method doesn't get fired quickly enough if the table view is scrolled fast. The result is that the UIView doesn't quite make all way back to its original position when scroll quickly.
The scroll content offset is a good idea. Also if you tableview has only one section one approach is to do a custom header view representing the top level widgets. If there is more than one sections create an additional empty section which would return your custom header.
You can refer to this stack overflow post.
Customize UITableview Header Section
Well Asked Question (y)
well , for me i would first : use a main UIScrollView that contains both your topView and the tableView under it and that has the same width as your top UIView and UITableView and set its height to be height(tableView) + height(topView).
Second : since UITableView is a subClass of UISCrollView you can use scrollViewDidScroll delegate to know if the tableview is scrolled up or down.
in this cas you will have Two cases :
1) tableview is scrolled up = > you set the content offset of the main scrollView to be
[scrollView setContentOffset:CGPointMake(0, 58) animated:YES];
2) when the table view is scrolled down you can reset the content offset again
[scrollView setContentOffset:CGPointMake(0, 0) animated:YES];