I noticed that Expedia app ( http://a5.mzstatic.com/us/r1000/027/Purple/4c/f4/6c/mzl.wcipbyyg.320x480-75.jpg) has a customized sectionIndex for UITableView on hotels list. (image attached)
I'm figuring that it could be a custom view, maybe with a vertical UISlider but, as I know, UISlider cannot recognize touch events on slides but just dragging ones.
So, how they do that ? A vertical sequence of buttons ? But, in this case, how to recognize dragging events ?
I would like to replicate that control but I need some hints ;)
thanks
There are more ways how to achieve the effect. Assuming you have a self.view initialized from a nib file and it's ordinary UIView, you can put this code into viewDidLoad:
- (void)viewDidLoad
{
CGRect tvFrame = self.view.frame;
tvFrame.origin = CGPointZero;
UITableView* tv = [[UITableView alloc] initWithFrame:self.view.frame];
tv.delegate = self;
tv.dataSource = self;
tv.showsVerticalScrollIndicator = NO;
[self.view addSubview:tv];
CGRect svFrame = CGRectMake(290, 10, 30, 400);
UIScrollView* sv = [[UIScrollView alloc] initWithFrame:svFrame];
sv.contentSize = CGSizeMake(10, 780);
sv.showsVerticalScrollIndicator = NO;
sv.bounces = YES;
CGRect vFrame = CGRectMake(10, 380, 10, 20);
UIView* v = [[UIView alloc] initWithFrame:vFrame];
v.backgroundColor = [UIColor blueColor];
[sv addSubview:v];
[self.view addSubview:sv];
[super viewDidLoad];
}
This will create a table with a narrow scroll view with a blue rectangle over the table. Now you can scroll both scroll views (the table is also a scroll view) independently.
Then you will have to setup delegates and receive scroll events via UIScrollViewDelegate. When one of the scroll views starts dragging, you have to start setting offset of the other scroll view.
Related
I have 2 problem and i am totally confuse. please help me
1) I face one problem that i want to assign click listener to image view which is inside of my subview and that subview is with in cell of UITableView.
In my tableview cell there are two image-view i want to give them click listener and also identify them like which image-view is clicked on which row etc etc.
if i write scrollview.userinteractionEnable=YES; than my didSelectRowAtIndexPath Not responds.
i know its because of subview.
But if i change scrollview.userinteractionEnable=NO; than my didselectrowatIndexpath code executes. but scrollview does not scroll to horizontal..
What do i do ? I want horizontal scroll plus Image-view click Listener on both ImageView.
** Solve click problem by crating scrollview sub class**
This is my Customcell class
cellScrollViewClass *scrollView = [[cellScrollViewClass alloc] initWithFrame:CGRectMake(0.0,0.0,430,187)];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3,scrollView.frame.size.height);
scrollView.scrollEnabled=YES;
scrollView.userInteractionEnabled=YES;
for (int i = 0; i < 3; i++) {
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
if(i==2) // to check Last item must be train Engine
{
UIView *EngineView = [[UIView alloc]initWithFrame:frame];
UIImageView *engineImageView = [[UIImageView alloc]initWithFrame:CGRectMake(-112.5, 6, 430, 180)];
UIImage *Image = [UIImage imageNamed:#"backengine.png"];
engineImageView.contentMode = UIViewContentModeScaleAspectFit;
engineImageView.image = Image;
[EngineView addSubview:engineImageView];
[scrollView addSubview:EngineView]; // add 3rd imageview that is Train Engine to end of scrollview
}
else{ // Not equal to 2 than it must be wagon of train.
UIView *wagon = [[UIView alloc]initWithFrame:frame];
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"wagon.png"]];
wagon.backgroundColor = background;
UIView *videoviewContainer = [[UIView alloc]initWithFrame:CGRectMake(20, 40, 220 , 200)];
UIImageView *videoImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0,0, 220, 100)];
UIImage *bgImage = [UIImage imageNamed:#"video.png"];
videoImageView.image = bgImage;
videoviewContainer.contentMode = UIViewContentModeLeft; // set Video Image view to left hand side of wagon UIView
videoImageView.tag=2;
[videoviewContainer addSubview:videoImageView];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[videoImageView addGestureRecognizer:singleTap];
[videoImageView setMultipleTouchEnabled:YES];
[videoImageView setUserInteractionEnabled:YES];
UIView *textUiView = [[UIView alloc]initWithFrame:CGRectMake(238,28, 150 , 187)];
textUiView.contentMode = UIViewContentModeRight;
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(28,10, 150 , 87)];
label.text=#"This is testing text for IOS app to check line are aligned or not and to check video image and nested views for UIviews";
label.backgroundColor = [UIColor clearColor];
label.textColor=[UIColor redColor];
label.numberOfLines = 4;
[textUiView addSubview:label];
[wagon addSubview:textUiView];
[wagon addSubview:videoviewContainer];
[scrollView addSubview:wagon];
[self.contentView addSubview:scrollView];
}
}
}
return self;
}
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
NSLog(#"Touch event on view %d",gesture.view.tag);
}
And I created Scrollview subclass like this..
#implementation cellScrollViewClass
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSLog(#"You are in scrollview");
}
return self;
}
IS this one is right method of Implementation?
Any Help is Appreciated . Thank you in advance.
Use UITapGestureRecognizer. Create and attach a tap gesture recogniser to each image view when you create it. Also set the tag of the image view when you create it so you can identify which one it is on the cell.
When you get the callback from the recogniser you can get the tag by:
recogniser.view.tag
And you can get the table view cell by looping on the superview until you find a table view cell class:
UIView *superView = recogniser.view.superview;
while (superView != nil && ![superView isKindOfClass:[UITableViewCell class]]) {
superView = superView.superview;
}
Then you can get the index path from the table view using
[tableView indexPathForCell:superView];
To get the on click listener for UIImageView have a category of it & use touches begin method and delegate callback to 'tableViewController'.
Use tags to identify which image is clicked & which row.
To avoid overlap, if the cell us already allocated just remove the previous images to do this have a else condition.
you need to implement the UIScrollView delegate callbacks and check what kind of scroll the user is doing (horizontal scroll or vertical scroll) and then changing the tableview or the scrollview offset manually, thats pretty much the only way i see this...
as for your image you need to set a UIButton for everyImage and link them to a selector, then you can use the tag of the button to know what image it was.
you can add a custom button over the imageview with same frame of image view and the you can add the selector on the button.
For handling gestures on UIImageView make sure that the UIImageView that you are using has the userInteractionEnable = YES by default is set to NO
In my split view application it is not possible to add search bar to the rootView of the split view
So i added search bar dynamically at the tableHeaderView of the ui table view as folows
searchBar = [[UISearchBar alloc] init];
searchBar.frame=CGRectMake(0, self.tableView.frame.origin.y, self.tableView.frame.size.width, 44);
[searchBar sizeToFit];
self.tableView.tableHeaderView = searchBar;
When Scroll down: iThe tableHeaderView also scrolls down so search bar also scrolls
When Scroll top: The tableHeaderView also scrolls top so search bar also scrolls
I implemented code as follows to resolve this issue this helps only when scrolls down but when we scrolls the table view to topside it again move with the table view
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect rect = self.tableView.tableHeaderView.frame;
rect.origin.y = MIN(0, self.tableView.contentOffset.y);
self.tableView.tableHeaderView.frame = rect;
}
I need to stick the tableHeaderView/ Search bar at the top of the view always
How to do this
You can add tabBar separate with tableView
mySearchBar = [[UISearchBar alloc] init];
[mySearchBar setHidden:NO];
mySearchBar.placeholder = #"Search item here";
mySearchBar.tintColor = [UIColor darkGrayColor];
mySearchBar.frame = CGRectMake(0, 0, 320, 44);
mySearchBar.delegate = self;
[mySearchBar sizeToFit];
[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[self.view addSubview:mySearchBar];
And tableView
UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 44, 320, 436)];
[self.view addSubview:tableView];
If You want to add in xib then
Put your searchBar in separate view and put that view above the table view. That means it stays constant.
I'm sure this has been answered before, but assuming you're using UITableViewController, you can make the view property be anything you want. So one approach would be to set up a container view with your search bar at the top and the table below it and make view be this container. By default, tableView returns view, so another detail you'd need to take care of is overriding the tableView property to return the actual table view (that you've stored in an ivar). The code might look something like this:
#synthesize tableView = _tableView;
- (void)loadView
{
[super loadView];
_tableView = [super tableView];
// Container for both the table view and search bar
UIView *container = [[UIView alloc] initWithFrame:self.tableView.frame];
// Search bar
UIView *searchBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 50)];
// Reposition the table view below the search bar
CGRect tableViewFrame = container.bounds;
tableViewFrame.size.height = tableViewFrame.size.height - searchBar.frame.size.height;
tableViewFrame.origin.y = searchBar.frame.size.height + 1;
self.tableView.frame = tableViewFrame;
// Reorganize the view heirarchy
[self.tableView.superview addSubview:container];
[container addSubview:self.tableView];
[container addSubview:searchBar];
self.view = container;
}
I added tableview to scrollview programmatically but it is not scrolling. While i tried the same using XIB. but it is working fine.
here is my code
CGRect frame = CGRectMake(30, 30.0f, 900, 300.0f);
eappTable = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
eappTable.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
eappTable.delegate = self;
eappTable.dataSource = self;
eappTable.scrollEnabled = YES;
eappTable.scrollsToTop = YES;
[eappTable reloadData];
[scrollView addSubview:eappTable];
eappTable = [[UITableView alloc] nitWithFrame:YourSize style:Table_Style]];
eappTable.delegate = self;
eappTable.dataSource = self;
eappTable.scrollEnabled = YES;
[scrollView addSubview:eappTable];
And set self.scrollView.contentSize
You have to set the Content Size of ScrollView.
Hope it Helps !!!
Try to enable bouncing (because if all cells size are smaller than the uitableview size it self, it won't scroll if bounce is set to NO) :
eappTable.bounces = YES;
[eappTable setContentSize:CGSizeMake(320, 680)];
I know this is not the answer you are looking for. But I would like to mention one point :
Never add tableview as the subview of your scrollview.
Important: You should not embed UIWebView or UITableView objects
in UIScrollView objects. If you do so, unexpected behavior can
result because touch events for the two objects can be mixed up and
wrongly handled.
From UIWebView Class Reference
I have one view Controller and one UIView now in my ViewController when i click barButton than second view will apear like popup,now i want to add page controller and scrollview in that second view, my second view is not UIViewController but it is UIView.so how can i do that...
my first view is "ImageViewController" and second view is "PopupView"
in ImageViewController.m
#import "PopupView.h"
#implementation ImageViewController
- (void)viewDidLoad
{
UIBarButtonItem *clipArt = [[UIBarButtonItem alloc] initWithTitle:#"Clip Art"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(popUpView:)];
}
- (void)popUpView:(id)sender {
CGRect * imageFrame = CGRectMake(10, 90, 300, 300);
PopupView *popUpView = [[PopupView alloc] initWithFrame:imageFrame];
[self.view addSubview:popUpView];
}
And in PopupView.m
- (id)initWithFrame:(CGRect)frame
{
if (self) {
CGRect * imageFrame = CGRectMake(0, 0, 300, 300);
self = [super initWithFrame:frame];
UIImageView *starImgView = [[UIImageView alloc] initWithFrame:imageFrame]; //create ImageView
starImgView.alpha =0.8;
starImgView.layer.cornerRadius = 15;
starImgView.layer.masksToBounds = YES;
starImgView.image = [UIImage imageNamed:#"black"];
[self addSubview:starImgView];
self.backgroundColor = [UIColor clearColor];
}
return self;
}
Implement like this in the second view, for scroll view with page control (this example illustrates the scenario for two views):
CGRect scrollViewFrame = CGRectMake(ur dimensions for scroll view);
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
myScrollView.pagingEnabled = YES;
myScrollView.contentSize = CGSizeMake(scrollViewFrame.size.width * 2, scrollViewFrame.size.height);
//content size is the actual size of the content to be displayed in the scroll view.
//Since, here we want to add two views so multiplied the width by two.
CGRect viewFrame = [myScrollView bounds];
UIView *view1 = [[UIView alloc] initWithFrame:viewFrame];
viewFrame.origin.x = viewFrame.size.width; //setting the offset so that view2 is next to view 1
UIView *view2 = [[UIView alloc] initWithFrame:viewFrame];
//add both the view to scroll view
[myScrollView addSubview:view1];
[myScrollView addSubview:view2];
//add scroll view to parent view
[self addSubview:myScrollView];
You can replace the view1/2 with any visual element. To have scrolling with page control make sure all the view that you want to add to scrollview are so same width/height. That way it work out of the box and you wont have to do anything. Also, its always a good idea to add UIPageControl to the view for giving user some kind of feedback. Its optional though.
One more thing, if you want horizontal scrolling with page control, increase the width as done above. If you want vertical scrolling, increase the height and keep the width same.
I was about to implement a table view behavior like the one used in a certain part of the twitter app for iPhone, precisely I'm talking about the tableview shown when, in a geolocalized tweet, I tap on the location displayed under the tweet. . .here's some pictures just to give it a look:
as you can see the table view has a background beneath (actually the map), but it is not just a background UIView (or Mapview) because the table view pulls it up and down with herself if the scrolling is about to "bounce". . .and it is certainly not a section header/footer, because the table floats on it. . .so, do you have any ideas on how to implement that table view? Could it be a webview?
edit: I found a solution and posted it down
just add the tableview and the mapview to a scrollview and you should be all set.
//CREATE THE SCROLL VIEW
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
scrollView.delegate = self;
scrollView.backgroundColor = [UIColor grayColor];
scrollView.contentSize = CGSizeMake(320, 650);
//ADDING TABLE VIEW
CGRect cgRct = CGRectMake(0, 0, 320, 600);
tblSimpleTable = [[UITableView alloc] initWithFrame:cgRct style:UITableViewStyleGrouped];
tblSimpleTable.delegate = self;
tblSimpleTable.dataSource = self;
[scrollView addSubview:tblSimpleTable];
//ADDING MAP VIEW
myMap = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
myMap.delegate = self;
[scrollView addSubview:myMap];
self.view = scrollView;
Maybe you can use UIView animations.
You add a mapview at the same height as your table view but with its alpha set to 0 in interface builder.
After that you can do as follow in your IBAction method:
[UIView beginAnimations:#"displayMapView" context:nil];
[UIView setAnimationDuration:0.3];
mapview.alpha = 1;
CGRect tableviewFrame = tableview.frame;
tableview.origin.y += 200; // Height of your map view
tableview.frame = tableviewFrame;
[UIView commitAnimations];
This should do it !
Or you can try somthing like this in your (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
IWebView* webView = [[UISynchedWebView alloc] initWithFrame:
CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
webView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
webView.tag = 1001;
webView.userInteractionEnabled = NO;
webView.delegate = self;
[cell addSubview:webView];
And load a Google Maps request or maybe put directly your mapview in your cell, haven't tried that.
Take a look at three20 library.
http://three20.info
and download source code from github at https://github.com/facebook/three20
In this framework there is a class named TTTableViewController that implement TTTableViewDragRefreshDelegate.
More, there an example application TTTwitter that use this class!
You can start from that and subclass to implement all features you need!
Ok I just figured it out. . .it was easy as hell. . .and was all about playing with the tableview first row, that has to be hidden to show the underlaying image, and the scrollview delegate that has to drag down with the tableview the underlying image when the dragging direction is down. . .here is the xcode project for you to give it a try :)
http://cl.ly/9bje