Display a tableView over another view - iphone

I would like to achieve a similar effect:
http://imageshack.us/m/695/3715/img0419s.png
My initial idea was to create something like presentend in this schema http://imageshack.us/m/9/9227/img0413.png. Ie a ViewController with 2 subviews: a classical one with some information, and a tableView below which should scroll over the previous view.
But I realized that dividing the main view this way couldn't allow my tableview to scroll over the first view.
So I'm asking how this effect is possible. Maybe by setting a transparent header ?
Thanks for your help

Following the teriiehina's advise, here is how I dit it :
In my UITableViewController, I set a 50px contentInset and a transparent color to my tableView.
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.contentInset = UIEdgeInsetsMake(50,0,0,0);
I added an additional view on the top of the view (same size than the contentInset)
TTView *test = [[TTView alloc] init];
test.frame = CGRectMake(0, 0, 320, 50);
test.backgroundColor = [UIColor grayColor];
[self.view addSubview:test];
Finally, in order to let my tableview scroll over the additional view, I brought it in the front
[self.view bringSubviewToFront:self.tableView];
Now I just have to set a custom color for my cells.

A dirty trick here:
Add the UIView that contains the name first
Add a UIScrollView with clipBounds = NO. That view will contain the message.
That should work for you

I think you can achieve this effect using the contentInset property of the UITableView (which is a UIScrollView subclass) and presenting the tableView at first with a programmatic scroll.

Related

Add scrollview iOS Objective-C

I have the following code in viewDidLoad on my ViewController:
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:204.0/255 green:00.0/255 blue:00.0/255 alpha:1];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
autoNameLabel.text = (NSString *)[vendorDetails objectForKey:#"autoname"];
homeLabel.text = (NSString *)[vendorDetails objectForKey:#"homelab"];
descriptionTextView.text = (NSString *)[vendorDetails objectForKey:#"description"];
This all fits perfectly on the view. I know need to add an additional textView on the bottom so need the user to be able to scroll to see it. How can I add this info to a scrollable view and add my additional textView?
you could have your UIViewController extend UISCrollViewController. Or you could add a UIScrollView to your view controller's view in the method viewDidLoad. Then add all subviews of your view to the scrollview instead.
self.scrollView = [[UIScrollView all] initWithFrame:self.view.bounds]
self.scrollView.contentSize = CGSizeMake(self.scrollView.bounds.width, HEIGHT_OF_SCROLLABLE_AREA).
I would also do something like this for the scroll view height if your last textview is named lastTextView
HEIGHT_OF_SCROLLABLE_AREA = CGRectGetMaxY(lastTextView.frame + bottomPadding)
Are you sure you dragged all the other views on the scrollview? Make sure the contentSize of the scrollview is high enough(you know, higher than the screen) to scroll.
have u set delegate of UIScrollView. if you have not set delegate of UIScrollView then also it may possible that your scroll is not working.

How to achieve UIPickerView as shown in image, with titles for components?

How to achieve picker view like this? I have implemented all necessary delegate and dataSource methods to populate the data, but the thing I am not able to understand is how to add this titles adults, children and infants?
They are static and does not spin with the component!
Add the 3 labels to your view as subviews when you showing the picker view and then hiding them when the picker is dismissed.
You will have to position the labels on the band.
I got this done just using Interface Builder.
I created a container view and then put picker view inside it.
To be sure that my container size is the same as picker view I set space constraints: leading, trailing, top and bottom.
Then I put 3 labels above picker view (but they're still the subviews of the container) and set their frames to center it.
Also to achieve the same label visual effect as on the screenshot (it seems to be under selection bar) decrease label's alpha to about 0.7.
You could put the labels on a particular frame position and then make the labels background color as clearColor.
You need to add labels as subviews of the picker view. There is no functionality built into UIPickerView to make this easy.
Create your picker, create a label with a shadow, and push it to a picker's subview below the selectionIndicator view.
It would look something like this
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(135, 93, 80, 30)] autorelease];
label.text = #"Label";
label.font = [UIFont boldSystemFontOfSize:20];
label.backgroundColor = [UIColor clearColor];
label.shadowColor = [UIColor whiteColor];
label.shadowOffset = CGSizeMake (0,1);
[picker insertSubview:label aboveSubview:[picker.subviews objectAtIndex:5]];
//When you have multiple components (sections)...
//you will need to find which subview you need to actually get under
//so experiment with that 'objectAtIndex:5'
//
//you can do something like the following to find the view to get on top of
// define #class UIPickerTable;
// NSMutableArray *tables = [[NSMutableArray alloc] init];
// for (id i in picker.subviews) if([i isKindOfClass:[UIPickerTable class]]) [tables addObject:i];
// etc...

Convert UIViewController to UIScrollViewController

I am new to iPad developer,
I made one Registration form in my application, when i see my application in Portrait mode,
i am able to see whole form with no scrolling, but when i see same form in Landscape mode, i am not able to see part which is at bottom of page, for that a scrolling should be there to see bottom part.
:
In my .h file when i replace
#interface ReminderPage : UIViewController{
...
...
}
:UIViewController with :UIScrollView
and then when i add label in my .m file like this,
UILabel *Lastpaidlbl = [[[UILabel alloc] initWithFrame:CGRectMake(70 ,400, 130, 50)]autorelease];
Lastpaidlbl.backgroundColor = [UIColor greenColor];
Lastpaidlbl.font=[UIFont systemFontOfSize:20];
Lastpaidlbl.text = #"Lastpaid on :";
[self.view addSubview:Lastpaidlbl];
I am getting error on last line Property view not found on object of type classname.
i am unable to add label in my view.
Any help will be appreciated.
The question appears to be really asking how can all the components on the screen be placed inside a UIScrollView, rather than a UIView. Using Xcode 4.6.3, I found I could achieve this by simply:
In Interface Builder, select all the sub-views inside the main UIView.
Choose Xcode menu item "Editor | Embed In | Scroll View".
The end result was a new scroll view embedded in the existing main UIView, will all the former sub-views of the UIView now as sub-views of the UIScrollView, with the same positioning.
If you want to replace your UIViewController with a UIScrollView, you will have to go a bit of refactoring to your code. The error you get is just an example of that:
the syntax:
[self.view addSubview:Lastpaidlbl];
is correct if self is a UIViewController; since you changed it to be UIScrollView, you should now do:
[self addSubview:Lastpaidlbl];
You will have quite a few changes like this one to make to your code and will face some issues.
Another approach would be this:
instantiate a UIScrollView (not derive from it);
add your UIView (such as you have defined it) to the scroll view;
define the contentSize of the scroll view so to include the whole UIView you have.
The scroll view acts as a container for your existing view (you add your controls to the scroll view, then add the scroll view to self.view); this way, you could integrate it within your existing controller:
1. UIScrollView* scrollView = <alloc/init>
2. [self.view addSubview:scrollView]; (in your controller)
3. [scrollView addSubview:<label>]; (for all of your labels and fields).
4. scrollView.contentSize = xxx;
I think the latter approach will be much easier.
Please put all of your UIComponents to the UIScrollview and then it will start scrolling.
please look in to content size. please change it according to the orientation of device.
You're subclassing UIScrollView, so there is no self.view because already self is the view (of the scrollview). You dont need to subclass the scrollview, you can just embed your components in a ivar scrollview and set its contentSize (in your case, you have to enable the scrolling just when the device is in landscape mode). In interface builder you can embed the selected elements in one click, Editor-> Embed in-> scrollview.
First create scrollview
UIScrollView * scr=[[UIScrollView alloc] initWithFrame:CGRectMake(10, 70, 756, 1000)];
scr.backgroundColor=[UIColor clearColor];
[ self.view addSubview:scr];
second
change [self.view addSubview:Lastpaidlbl];
to
[scr addSubview:Lastpaidlbl];
third
set height depends on content
UIView *view = nil;
NSArray *subviews = [scr subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
CGRect frame = view.frame;
curXLoc += (frame.size.height);
}
// set the content size so it can be scrollable
[scr setContentSize:CGSizeMake(756, curXLoc)];
Finally
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight) {
self.scr.frame = CGRectMake(0, 0, 703,768);
} else {
self.scr.frame = CGRectMake(0, 0, 768, 1024);
}
return YES;
}

Why does UIScrollView always scrolls to bottom?

I have seen this question being addressed several times here at SO, e.g Problem with UIScrollView Content Offset, but I´m still not able to solve it.
My iphone app is basically a tab bar controller with navigation bar. I have a tableview controller made programmatically and a DetailViewController that slides in when I tap a cell in my tableview controller.
The DetailViewController is made in IB and has the following hierarchy:
top view => UIScrollView => UIView => UIImage and a UITextField.
My goal is to be able to scroll the image and text field and this works well. The problem is that my UIScrollView always gets positioned at the bottom instead at the top.
After recommendations her at SO, I have made my UIScrollView same size as the top view and instead made the UIView with the max height (1500) of my variable contents.
In ViewDidLoad I set the contentSize for the UIScrollView (as this is not accessible from IB):
- (void)viewDidLoad {
[scrollView setContentSize:CGSizeMake(320, 1500)];
[scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
NSLog(#"viewDidLoad: contentOffset y: %f",[scrollView contentOffset].y);
}
Specifically setting the contentOffset, I would expect my scrollView to always end up at the top. Instead it always go to the bottom. It looks to me that there is some autoscrolling beyond my control taking place after this method.
My read back of the contentOffset looks OK. It looks to me that there may be some timing related issues as the scrolling result may vary whether animation is YES or NO.
A ugly workaround I have found is by using this delegate method:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrView {
NSLog(#"Prog. scrolling ended");
[scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
}
This brings my scrollview to top, but makes it bounce down and up like a yo-yo
Another clue might be that although my instance variables for the IBOutlet are set before I push the view controller, the first time comes up with empty image and textfield:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!detailViewController) {
detailViewController = [[DayDetailViewController alloc] init];
}
// Pass dictionary for the selected event to next controller
NSDictionary *dict = [eventsDay objectAtIndex:[indexPath row]];
// This method sets values for the image and textfield outlets
[detailViewController setEventDictionary:dict];
// Push it onto the top of the navigation controller´s stack.
[[self navigationController] pushViewController:detailViewController animated:NO];
}
If I set animation to YES, and switch the order of the IBOutlet setting and pushViewController, I can avoid the emptiness upon initialization. Why?
Any help with these matters are highly appreciated, as this is really driving me nuts!
Inspired of Ponchotg´s description of a programmatically approach, I decided to skip interface builder. The result was in some way disappointing: The same problem, with the scrollview ending up in unpredictable positions (mostly at bottom), persisted.
However, I noticed that the scroll offset error was much smaller. I think this is related to the now dynamic (and generally smaller) value of ContentOffset. After some blind experimenting I ended up setting
[textView setScrollEnabled:YES];
This was previously set to NO, as the UITextView is placed inside the scrollview, which should take care of the scrolling. (In my initial question, I have erroneously said it was a UITextField, that was wrong)
With this change my problem disappeared, I was simply not able to get into the situation with scrollview appearing at bottom anymore in the simulator! (At my 3G device I have seen a slight offset appear very seldom, but this is easily fixed with scrollViewDidEndScrollingAnimation delegate described previously ).
I consider this as solved now, but would appreciate if anyone understand why this little detail messes up things?
OK! i have a question before i can give a correct answer.
Why are you using a UIView inside the Scrollview?
You can always only put your UIImageView and UITextField inside the UIScrollView without the UIView
and set the contentSize dynamically depending on the size of the text.
to give you an example how i do it:
int contSize = 0;
imageView.frame = CGRectMake(10, 0, 300, 190);
imageView.image = [UIImage imageNamed:#"yourimage"];
contSize = 190 //or add extra space if you dont want your image and your text to be so close
[textField setScrollEnabled:NO];
textField.font = [UIFont systemFontOfSize:15];
textField.textColor = [UIColor grayColor];
textField.text = #"YOUR TEXT";
[textField setEditable:NO];
textField.frame = CGRectMake(5, contSize, 310, 34);
CGRect frameText = textField.frame;
frameText.size.height = textField.contentSize.height;
textField.frame = frameText;
contSize += (textField.contentSize.height);
[scrollView setScrollEnabled:YES];
[scrolView setContentSize:CGSizeMake(320, contSize)];
In the above example I first create an int to keep track of the ysize of my view then Give settings and the image to my UIImageView and add that number to my int then i give settings and text to my UITextField and then i calculate the size of my text depending on how long is my text and the size of my font, then add that to my int and finally assign the contentSize of my ScrollView to match my int.
That way the size of your scrollview will always match your view, and the scrollView will always be at top.
But if you don't want to do all this, you can allways just:
[scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
at the end of the code where you set your image and your text, and the NOto avoid the bouncing.
Hope this helps.

Light gray background in "bounce area" of a UITableView

Apple's iPhone apps such as Music and Contants use a search bar in a UITableView. When you scroll down so that the search bar moves down, the empty space above the scroll view's contents has a light gray background color (see screenshot).
(Notice that the search bar has a slightly darker edge line at its top. This is not there for the default UISearchBar, but subclassing should take care of that.)
I tried setting the background color of the UITableView, but that affects the rows as well. Does anyone know how to achieve this effect? Am I going to have to override implement drawRect: or is there a built in way?
Setting transparencies is bad for performance. What you want is the gray area above the search bar, but it should still be white beyond the end of the list.
You can add a subview to your UITableView that lives above the content instead.
CGRect frame = self.list.bounds;
frame.origin.y = -frame.size.height;
UIView* grayView = [[UIView alloc] initWithFrame:frame];
grayView.backgroundColor = [UIColor grayColor];
[self.listView addSubview:grayView];
[grayView release];
You could add more fancy stuff to the view if you like, perhaps a fade, or a divider line without subclassing UISearchBar.
This is one of my very favorite tricks.
UIView *topview = [[[UIView alloc] initWithFrame:CGRectMake(0,-480,320,480)] autorelease];
topview.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:238.0/255.0 alpha:1];
[self.tableView addSubview:topview];
Basically you're creating a big view the size of the screen and placing it "above" the content area. You'll never be able to scroll up past it.
And don't worry about the memory impact of a UIView that's 320x480 pixels, it won't consume any significant memory because the CALayer doesn't have any meaningful content.
NOTE: Why is this answer relevant when the "accepted" answer is so much simpler? Why not just set the backgroundView on the table view? It's because, in the case of the Contacts app as shown in the original question, the area "above" the table view has a different background color (light blue) than the area "below" the table view (white). This technique allows you to have two different colors above and below the table view, which cannot be accomplished by a simple background.
EDIT 1/2018: As Tom in the comments pointed out, this answer is quite old and assumes that all iOS devices have the same screen size (seems crazy but it was the case in 2009 when I answered this). The concept I present here still works, but you should use UIScreen.main.bounds to figure out the actual screen size, or you could get into some fancy auto layout stuff (suggestions welcome). I don't recommend using tableView.bounds as in another answer, because typically in viewDidLoad the size of your views is not necessarily the size that they will become after the controller resizes them. Sometimes they start out as 0x0!
To extend on HusseinB's suggestion:
Swift 3
let bgView = UIView()
bgView.backgroundColor = UIColor.white
self.tableView.backgroundView = bgView
Objective C
UIView *bgView = [UIView new];
bgView.backgroundColor = [UIColor whiteColor];
[self.tableView setBackgroundView:bgView];
As of iOS 7, you can tinker this by changing the tableview background view.
[self.tableView setBackgroundView:view];
make the view's background colour the same as your parent view colour.
This code works in Swift fot UITableView:
var frame = self.tableView.bounds
frame.origin.y = -frame.size.height
frame.size.height = frame.size.height
frame.size.width = UIScreen.mainScreen().bounds.size.width
let blueView = UIView(frame: frame)
blueView.backgroundColor = UIColor.headerBlueColor()
self.tableView.addSubview(blueView)
In Swift (tested on iOS9)
let backView = UIView(frame: self.tableView.bounds)
backView.backgroundColor = UIColor.clearColor() // or whatever color
self.tableView.backgroundView = backView
EASIEST SOLUTION
The easiest way to create different colors in the bottom and in the top of a bouncing area of a table view is to set the key tableHeaderBackgroundColor of the table view. Doing this way you set the top color. I'm not sure, but maybe there is another key for the footer, take a look. If you don't find anything, you just have to set the background of the table view with the color that you want to show in the bottom. Above you can see an example code:
self.table.setValue(UIColor.blue , forKey: "tableHeaderBackgroundColor")
Hope it help you. If yes, let other people know about this easy way giving an up in the answer :)
I've only found one way to do this. You have to set the backgroundColor of the UITableView to be transparent, set the backgroundColor of the cell's contentView to whatever colour you want the actual cells to be, then crucially you have to get the light grey colour to appear behind the UITableView. That last step you can do by either setting the backgroundColour of the UIWindow, or of whatever is containing or your tableViewController.
So, assuming you have a view controller that is derived from UITableViewController, insert these lines in the -(void)viewDidLoad method:-
// sets the background of the table to be transparent
self.tableView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.0];
// assuming we are inside a navigation or tab controller, set the background
self.parentViewController.view.backgroundColor = [UIColor lightGrayColor];
Then inside the part of tableView:cellForRowAtIndexPath: that creates new cells, add:-
// set an opaque background for the cells
cell.contentView.backgroundColor = [UIColor whiteColor];
I just encountered this issue myself and found a solution.
Cause
I used Spark Inspector to examine the layout of the table view - which really helped.
Thing is, that in this scenario the UITableView has 3 subviews:
UITableViewWrapperView
UIView - With backgroundColor set to light gray color
UISearchBar
While you swipe the tableview content downwards, the second subview height is dynamically increasing to fill the space between the UITableViewWrapperView and the UITableView frame origin.
Solution
Setting the backgroundColor or backgroundView property won't effect the 2nd subview.
What you need to do is find the second view and change its color, like so:
if (_tableView.subviews.count > 1) {
_tableView.subviews[1].backgroundColor = THE_TARGET_COLOR;
}
In my case I needed all views to be white so I used the following which is less prone to future changes of UITableView view hierarchy by Apple:
for (UIView *subview in _tableView.subviews) {
subview.backgroundColor = [UIColor whiteColor];
}
I will give you the best way to do this.
First set the background color of the table view to the one you want in interface builder.
Then respond to the UITableView delegate tableView:willDisplayCell:ForIndexPath: method
like this
- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCelll*)cell forIndexPath:(NSINdexPath*)indexPath
{
[cell setBackgroundColor:[UIColor whiteColor]];
}
Another Method is :
in ViewDidLoad method (or anywhere you like) set the tableView background color to clear color like this:
self.tableView.backgroundColor = [UIColor clearColor];
and then set the superview color to white
self.tableView.superview.backgroundColor = [UIColor whiteColor];
I don't think you want to override drawRect. Most likely what you're seeing is the background colour of another view or the window, which lies "behind" (i.e. is a superview of) the table view. There's usually a fairly complex layers of UIViews in Apple's UI widgets. Explore the view hierarchy in GDB, look at [myView superview] and then [someSuperView subviews] and try manipulating their BG colours in the debugger to see if you can find which one it is. However, if you implement a fix this way, be warned that it may not be future compatible.
You might also try setting the BG colour of one of the views behind the tableview in Interface Builder (or of the window itself).
If you are using a tableviewcell, you can set the view background to be opaque white. Then use
self.tableView.backgroundColor = [UIColor grayColor];
in the view did load method.
I'm sure that that is [UITableView backgroundColor].
You have affected rows, because rows have backgroundColor == clear (or semi-transparent).
So, If you'll make rows non-trasparent, all will work fine.
This will be solution.
I followed the tip outlined by Peylow, for a UITableView, by simply adding a subview. My only change from the code was to grab a color a bit closer to the one used in Apple apps, plus I got it a bit closer to Apple's look of having a line above the UISearchbar by reducing the frame origin y coordinate by one pixel:
frame.origin.y = -frame.size.height - 1
For anyone who's wondering how to do the same for the bottom bounce area:
First add a subview with your desired background color to your table view's background view:
self.bottomView = [[UIView alloc] initWithFrame:CGRectOffset(self.tableView.frame, 0, self.tableView.frame.size.height)];
self.bottomView.backgroundColor = whateverColorYouLike;
[self.tableView.backgroundView addSubview:self.bottomView];
And then in your table view's delegate:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = self.bottomView.frame;
frame.origin.y = self.tableView.contentSize.height - self.tableView.contentOffset.y;
self.bottomView.frame = frame;
}
In my case the solution was to create a headerview for the table and assign a color, it solved the black background in bounce area in my apps when in dark mode. I did the same to its tableFooterView.
table.tableHeaderView = UIView()
table.tableHeaderView!.backgroundColor = UIColor.white