scroll top and bottom with page control - ios6

Using scrollview with page control for displaying different pages. want to scroll up and down on each page. How can i do that.
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width * 3, self.view.frame.size.height)];
[scrollView setDelegate:self];
[scrollView setPagingEnabled:YES];
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
// Add our views to the scroll view
[scrollView addSubview:pageOne.view];
[scrollView addSubview:pageTwo.view];
[scrollView addSubview:pageThree.view];
[self.view addSubview:self.scrollView];
_pageControl = [[UIPageControl alloc] init];
[_pageControl setCurrentPage:0];
[_pageControl setNumberOfPages:3];
[_pageControl sizeToFit];
[_pageControl setFrame:CGRectMake((scrollView.frame.size.width / 2) - (_pageControl.frame.size.width / 2), scrollView.frame.size.height - _pageControl.frame.size.height, _pageControl.frame.size.width, _pageControl.frame.size.height)];
[self.view addSubview:self.pageControl];
How can i enable scrolling up and down on each page.
Thanks for help.

You need to monitor the UIControlEventValueChanged event to determine when the page control has changed pages. You can do this programmatically view the addTarget method.
[_pageControl addTarget:self action:#selector(positionChanged)
forControlEvents:UIControlEventValueChanged];
This tells the page control to call the positionChanged method in the current object, whenever the page is changed. The positionChanged method can then look at the currentPage of the page control to determine where to move to.
So the positionChanged method might look something like this:
- (void)positionChanged {
NSUInteger page = [_pageControl currentPage];
CGFloat yoffset = self.view.frame.size.height * page;
[scrollView setContentOffset:CGPointMake(0,y)];
}
Don't forget that you'll need to call removeTarget sometime before your object is destroyed, possibly in your dealloc method.
[_pageControl removeTarget:self action:#selector(positionChanged)
forControlEvents:UIControlEventValueChanged];
Code hasn't been tested, but hopefully that's enough to get you started.
If you don't want to do this programmatically, you can also connect your page control to the positionChanged method using the Xcode Interface Builder. The details are explained in the Xcode User Guide.

Related

Programmatically show and hide the popover (MasterViewController) in UISplitViewController (Master-Detail Template)

I want to add a button that show/hides the popover, similarly to the one of the DropBox app.
(In both landscape & portrait)
I have tried many solutions, but at this stage I don't even want to muddy the water with my attempts. If you've done this, or know how to do this, please send me in the right direction!
Thanks!
it appears it's quite simple.
Set some object to be delegate of splitViewController. In my case (I create all viewcontrollers programatically) that was appdelegate.
UISplitViewController* splitViewController = [[UISplitViewController alloc] init];
[splitViewController setViewControllers:#[navigationViewController1, navigationViewController2]];
splitViewController.delegate = self;
Implement delegate method to hide master in portrait orientation:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
return UIInterfaceOrientationIsPortrait(orientation);
}
Actually add barButtonItem:
-(void)splitViewController:(UISplitViewController *)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem *)barButtonItem
forPopoverController:(UIPopoverController *)pc {
UINavigationController* slaveNavigationViewController = svc.viewControllers[1];
UIViewController* slaveViewController = slaveNavigationViewController.viewControllers[0];
[barButtonItem setTitle:#"Your master title"];
slaveViewController.navigationItem.leftBarButtonItem = barButtonItem;
}
In this method, you get barButtonItem which you customize and add to slaveViewController.
And last one, remove the button in landscape orientation:
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
UINavigationController* slaveNavigationViewController = svc.viewControllers[1];
UIViewController* slaveViewController = slaveNavigationViewController.viewControllers[0];
[barButtonItem setTitle:#"Drops"];
slaveViewController.navigationItem.leftBarButtonItem = nil;
}
That's it.
There's a simpler, undocumented way to do it. For an existing UIButton:
[button addTarget: theSplitViewController action: #selector(toggleMasterVisible:) forControlEvents:UIControlEventTouchUpInside];
This target/action are the same as for the barButtonItem sent in the willHideViewController function.

Rotation Not working in iOS-6.0 and above versions

I have prepared one view controller file named "CncWindowController" and In XIB file, i take window object (instead of UIView) and connected it to view outlet. So when I access its view, i get window object.
I'm accessing like it in AppDelegate.m file :
self.windowController = [[CncWindowController alloc] initWithNibName:#"CncWindowController" bundle:nil];
self.window = (UIWindow*) self.windowController.view;
Here, view is actually referring to window. But Rotation is not working in iOS6.0 and shouldAutorotate method is also not called.
If i will use window object like below then it works fine :
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
What is wrong with my approach ? Any help of ideas how i should work autorotation in iOS-6 too using above approach ?
Thanks!

iCarousel integration to app having Tab bar controller in iOS 6.1

I integrate the iCarousel app with single view application.But when I add the tab bar controller and place this iCarousel code in one tab bar Item viewcontroller.But it does not work(Items are displayed but not scrolled).What is the problem here.
I created iCarousel as below:
iCarousel *categorySubView = [[iCarousel alloc]initWithFrame:CGRectMake(0,200, 300, 125)];
categorySubView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
categorySubView.delegate = self;
categorySubView.dataSource = self;
categorySubView.type=iCarouselTypeRotary;
[self.view addSubview:categorySubView];
I am using the following delegae and data source methods:
-(NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return 5;
}
- (UIView *) carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
UIView *sampleView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 250, 300)];
sampleView.backgroundColor=[UIColor whiteColor];
UILabel *labelis=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, 100, 20)];
labelis.backgroundColor=[UIColor clearColor];
labelis.text=#"8Apr-14Apr";
[sampleView addsubView:labelis];
return sampleView;
}
Please suggest me.
Thanks inadvance
I notice that your carousel view is much smaller than the size of the items inside it (it's only 125 points high).
iCarousel can draw outside of its bounds, but it cannot detect touch events outside of its bounds, so that might be why you are having trouble scrolling.
A good way to debug this is to set the carousel.clipsToBounds = YES, that way what it draws will match what is touchable. Another option is to set the carousel.backgroundColor so you can see what part of it is touchable on screen.
Another thing to check is that the view that you've placed the carousel inside has userInteractionEnabled set to YES.

Pull-to-refresh in UICollectionViewController

I want to implement pull-down-to-refresh in a UICollectionViewController under iOS 6. This was easy to achieve with a UITableViewController, like so:
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(startRefresh:)
forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
The above implements a nice liquid-drop animation as part of a native widget.
As UICollectionViewController is a "more evolved" UITableViewController one would expect somewhat of a parity of features, but I can't find a reference anywhere to a built-in way to implement this.
Is there a simple way to do this that I'm overlooking?
Can UIRefreshControl be used somehow with UICollectionViewController despite the header and docs both stating that it's meant to be used with a table view?
The answers to both (1) and (2) are yes.
Simply add a UIRefreshControl instance as a subview of .collectionView and it just works.
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(startRefresh:)
forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];
That's it! I wish this had been mentioned in the documentation somewhere, even though sometimes a simple experiment does the trick.
EDIT: this solution won't work if the collection is not big enough to have an active scrollbar. If you add this statement,
self.collectionView.alwaysBounceVertical = YES;
then everything works perfectly. This fix taken from another post on the same topic (referenced in a comment in the other posted answer).
I was looking for the same solution, but in Swift. Based on the above answer, I have done the following:
let refreshCtrl = UIRefreshControl()
...
refreshCtrl.addTarget(self, action: "startRefresh", forControlEvents: .ValueChanged)
collectionView?.addSubview(refreshCtrl)
Not forgetting to:
refreshCtrl.endRefreshing()
I was using Storyboard and setting self.collectionView.alwaysBounceVertical = YES; did not work. Selecting the Bounces and Bounces Vertically does the job for me.
The refreshControl property has now been added to UIScrollView as of iOS 10 so you can set the refresh control directly on collection views.
https://developer.apple.com/reference/uikit/uiscrollview/2127691-refreshcontrol
UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:#selector(refreshControlAction:) forControlEvents:UIControlEventValueChanged];
self.collectionView.refreshControl = refreshControl;
mjh's answer is correct.
I ran into the issue where if the the collectionView.contentSize was not larger then the collectionView.frame.size, you can not get the collectionView to scroll. You can not set the contentSize property either (at least I couldn't).
If it can't scroll, it won't let you do the pull to refresh.
My solution was to subclass UICollectionViewFlowLayout and overide the method:
- (CGSize)collectionViewContentSize
{
CGFloat height = [super collectionViewContentSize].height;
// Always returns a contentSize larger then frame so it can scroll and UIRefreshControl will work
if (height < self.collectionView.bounds.size.height) {
height = self.collectionView.bounds.size.height + 1;
}
return CGSizeMake([super collectionViewContentSize].width, height);
}

Why does the MPMoviePlayerController call MPMoviePlayerPlaybackDidFinishNotification, when enter in fullsceen mode

I want to display a MPMoviePlayerViewController in full screen mode, but when the fullscreen button of the movieplayercontroller view is beeing pressed, first the MPMoviePlayerWillEnterFullscreenNotification gets called, as expacted, but than the MPMoviePlayerPlaybackDidFinishNotification is also beeing sent. As a reason it says MPMovieFinishReasonPlaybackEnded and i don't know, what i'm doing wrong. (In addition, i use iOS 6.0 and XCode 4.5.1)
My expactations are, that only the MPMoviePlayerWillEnterFullscreenNotification is beeing called.
Short explanation to the code below:
The MovieplayerViewController's view is beeing displayed in a tiny subview in my content view. When tapping the fullscreen-button, it first gets displayed as fullscreen but than also calls the exit button and stops playing (no crashes, nothing else).
MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[playerViewController.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[playerViewController.moviePlayer setScalingMode:MPMovieScalingModeFill];
CGRect rect = videoView.frame;
rect.origin = CGPointZero;
[playerViewController.view setFrame:rect];
[playerViewController.moviePlayer prepareToPlay];
//movie this is my contents subview, where i add the viewcontroller's view as a subbview
[self.videoView addSubview:playerViewController.view];
[self.videoView setHidden:NO];
playerViewController.moviePlayer.useApplicationAudioSession = NO;
[playerViewController.moviePlayer play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerDidFinishNotification:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerViewController.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillEnterFullscreenNotification:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:playerViewController.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillExitFullscreenNotification:)
name:MPMoviePlayerWillExitFullscreenNotification
object:playerViewController.moviePlayer];
//i store the movieplayer in a property, so i can use it for further operations
self.myPlayer = playerViewController;
[playerViewController release];
And thats it!
When the resize (or fullscreen) button is being pressed, the moviePlayerDidFinishNotification: method also is being called
- (void)moviePlayerDidFinishNotification:(NSNotification*) aNotification {
int reason = [[[aNotification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
//movie finished playin
//in debug mode, it stops right at the NSLog
NSLog(#"");
}
else if (reason == MPMovieFinishReasonUserExited) {
//user hit the done button
}
else if (reason == MPMovieFinishReasonPlaybackError) {
//error
}
.. }
Is there something i do wrong or is there probably a change since iOS 6.0?
Ok, seems to be that there are some problems in the MPMoviePlayerViewController. What helped is to simply us the MPMoviePlayerController only.
For future reference the reason that your player showed in a small window was because you were setting:
[playerViewController.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[playerViewController.moviePlayer setScalingMode:MPMovieScalingModeFill];
CGRect rect = videoView.frame;
rect.origin = CGPointZero;
[playerViewController.view setFrame:rect];
[playerViewController.moviePlayer prepareToPlay];
//movie this is my contents subview, where i add the viewcontroller's view as a subbview
[self.videoView addSubview:playerViewController.view];
[self.videoView setHidden:NO];
When you use an MPMoviePlayerViewController it creates it's own view controller. These calls are not necessary and will only create bizarre behavior. That's why the MPMoviePlayerController worked properly because it's designed to work inside another view controller.

Resources