So what I'm trying to do is to write a simple gallery app - detail view behaves pretty much like the PhotoScroller provided by Apple in their sample code section on developer.apple.com, that is it allows the user to swipe across all the images. What I'd like to do is to update the title property on users swipe, in other words, if the user changes the image she's looking at, the self.title property should update itself to that photo's title. I know that is possible, since Apple's own Photo app is capable of displaying the current index ("1 of x"). How can this be done? I'd really appreciate any suggestions and thank you in advance.
When you scroll the ScrollView after ending the scrolling
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
method is call. So You can give the title inside this method. First Make an array of your all
Image's title. Then if your image's width is 320, then use this :-
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int index = scrollView.contentOffset.x / 320;
self.title = [titleArray objectAtIndex:index];
}
If you are putting images in a scroll view then this method will give you the page number you are currently in:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);
NSLog(#"page no is:%d",pageNum);
[self updateTitleForIndex: pageNum];
}
- (void)updateTitleForIndex:(NSInteger) pageNum
{
//set title using your page number
//also call this method initially for setting title
}
If you're using a paged UIScrollView, the best approach would be to do the manipulation of the title in the delegate method called
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
You should use a method of UIScrollViewDelegate protocol, such as -scrollViewDidScroll:
Related
Are there any examples of infinite vertical scrollview, something like Facebook and 9gag app. When you scroll it shows for example pictures, but it stops after lets say 10 pictures showing refresh/loading indicator, and then loading new pictures (so it doesn't have to download all pics at app start).
Thanks.
This amazing dev has made it easy to add infinite scroll with a UIScrollView category. You should probably give it a try.
when user scroll upside then it call the following method
#pragma mark -
#pragma mark - Scroll View Delegate Method
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == scrollObj) {
CGFloat scrollPosition = scrollObj.contentSize.height - scrollObj.frame.size.height - scrollObj.contentOffset.y;
if (scrollPosition < 30)
{
if ((!spinnerBottom.isAnimating) ) {
[spinnerBottom startAnimating];
[self getAPICall]; //your apicall function
}
}
}
}
How do I check/call a method when a user is at the bottom of the UIWebView when scrolling? I want to popup a view (add a subiview) when the user is at the bottom of the content.
Building on other ideas here, UIWebView conforms to the UIScrollViewDelegate protocol. You could subclass UIWebView and override the appropriate UIScrollViewDelegate methods, calling [super ...] so the original behavior is still present.
#interface SpecialWebview : UIWebView
#end
#implementation SpecialWebview
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[super scrollViewDidScroll:scrollView];
// Check scroll position and handle events as needed...
}
#end
First get the reference to the UIWebView scrollView using this property:
#property(nonatomic, readonly, retain) UIScrollView *scrollView
Once you get the reference to it you could check for the contentSize of it and compare it with the contentOffSet. You cannot make yourself a delegate of it, since the UIWebView is already the delegate for the scrollView, but that trick should work.
The problem is that you don't get the callBack when the scrolling is happening... so you would have to check every so often. Otherwise you will have to make yourself the delegate of the scrollView, and implement all the methods that UIWebView is implementing and mimic that behavior, and then check on the didScroll for that condition.
Another option would be to inject some JavaScript into the web view and then use the window.onscroll event in JavaScript to detect when the user has scrolled to the bottom of the window (you can find plenty of examples online if detecting scroll events using JS).
Once you detect the the user is at the bottom, you could call back to the app by loading a fake url in the web view from the JavaScript by saying document.location.href = "http://madeupcallbackurl", then use the web view delegate to intercept that request and perform your native code logic.
Using the scrollview delegate is probably easier though if you can make that work!
Sorry, I was thinking UITableView. You are asking about a UIWebView. I don't know if this will work with the UIWebView.
I have code that does this using a UIScrollViewDelegate.
#interface myViewController : UIViewController_iPad <UIScrollViewDelegate> {
UITableView *myTableView;
...
}
- (void)viewDidLoad {
myTableView.delegate = self;
...
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// If necessary, verify this scrollview is your table:
// if (scrollView == myTableView) {
CGPoint offset = myTableView.contentOffset;
if (myTableView.contentSize.height - offset.y >= myTableView.bounds.size.height)
{
// The table scrolled to the bottom. Do your stuff...
}
// }
}
This is how I would do it.
UIWebView conforms to UIScrollViewDelegate. Use the - (void)scrollViewDidScroll:(UIScrollView *)scrollView callback to keep track of when your UIWebView is scrolling:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//The webview is is scrolling
int xPosition = [[webView stringByEvaluatingJavaScriptFromString: #"scrollX"] intValue];
int yPosition = [[webView stringByEvaluatingJavaScriptFromString: #"scrollY"] intValue];
}
Now this method will be invoked whenever your webView scrolls. Your webView will have scrolled to the bottom when:
webView_content_height - webView(y) = webView.frame.height; //pseudo code
Your delegate callback will now look like:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//The webview is is scrolling
int xPosition = [[webView stringByEvaluatingJavaScriptFromString: #"scrollX"] intValue];
int yPosition = [[webView stringByEvaluatingJavaScriptFromString: #"scrollY"] intValue];
if([webView stringByEvaluatingJavaScriptFromString: #"document.body.offsetHeight"] - yPosition == webView.frame.height)
{
//The user scrolled to the bottom of the webview
}
}
What the code translates to is that when the user scrolls to the bottom of the content, the difference between the webView's y Position (which is the y-coordinate of the webView's top left corner) and the bottom of the content will be equal to the height of the webview frame. The code acts upon this condition being satisfied to enter inside the if condition.
To be on the safe side, you could modify the if condition to have a margin for error (maybe + or - 10 pixels).
I have a UIScrollView that contains large images and am using paging to scroll between images. In order to save memory, I am loading only one image before and after the currently visible one and loading/releasing new images after a scroll has completed. The problem occurs when one scrolls quickly and scrollViewDidEndDecelerating is not called.
When the scrollViewDidEndDecelerating is called I wanted to display the image name in the active page.
How do I solve this? Why does this happens?
scrollViewDidEndDragging will call after each scroll complete
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{}
scrollViewDidEndDecelerating don't call in each drag (if you don't drag with acce speed after draged stop it will don't never call this func)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{}
scrollViewDidEndScrollingAnimation if you want move the scroll view use api not with drag, this api will called.
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{}
Im doing the same thing with a scroll view - lazy loading of images. We actually had to load a thumbnail that is stretched (making a blurry low res version of the image) and then load the real image when the page is actually being displayed 100% in view.
What I had to do was use the following code in the scrollViewDidScroll:scrollView.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!_isCurrentlyRotating) {
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth)+1;
if (_currentPage != page)
[self setCurrentPage:page];
}
}
The above calculates the page that is going to be displayed (as your scrolling). It will actually change the current page number when the page view is 50% displayed. This can be used in conjunction with the page control to highlight the current page dot.
Using the above, (with paging enabled on the scroll view) when the user uses their finger to change the page (the normal behavior) scrollViewDidEndDecelerating:scrollView is called when the page is 100% displayed. By 100% I mean you can only see one page not part of one part of another.
But we have a 'Start Over' button at the end of the scroll view that calls my scrollToPage: function.
- (void) scrollToPage:(int)page {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * page;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
}
Using scrollRectToVisible:animated: method does not trigger the scrollViewDidEndDecelerating: method so I simply added the sharpen method (which simply loads te high res image in the image view) call to both methods so that it will be called if the user scrolls or if the start over button is pressed.
- (void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
[self sharpenImageView];
}
- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self sharpenImageView];
}
I hope this helps!
Check if your UIScrollView's delegate is set or not, or was set to nil.
Normally set in this way scrollView.delegate = self.
scrollViewDidEndDecelerating: is not meant to do your page layout in. You should implement scrollViewDidScroll: and calculate the currently visible page(s) based on the contentOffset of the scroll view. If the visible range has changed, add views for the pages that were previously not visible and remove those that are no longer visible.
Sometimes just clean your project and re-run
Shift & Cmd & K
Shift & Cmd & Alt & k
So, I have a UIView with a UIWebView inside serving up a local HTML file (a document preview). I also have "Accept" & "Reject" UIButtons. I need these buttons to only appear after the user has scrolled to the bottom of the web page. Is there a way to capture an event for scrolling to the bottom of a UIWebView?
I have not seen any good answers for this, can anyone help?
Thanks in advance.
UIWebView conforms to UIScrollViewDelegate. As such, you can create a subclass of UIWebView (say, ScrollDetectWebView) and capture the calls to the UIScrollViewDelegate.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[super scrollViewDidScroll: scrollView];
// Whatever scroll detection you need to do
}
huh?
Why not just included the buttons on the bottom of the page?
JavaScript lets handle the scrolling event and send message to Objective-c.
- (void)viewDidLoad {
[super viewDidLoad];
self.webView.scrollView.delegate = self;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGSize fittingSize = [self.webView sizeThatFits:CGSizeZero];
CGFloat height1 = scrollView.bounds.origin.y + self.webView.bounds.size.height;
CGFloat height2 = fittingSize.height;
int delta = fabs(height1 - height2);
if (delta < 30) {
NSLog(#"HELLO!!! You reached the page end!");
}
}
I've searched and searched for a tutorial for this but none of them are what I'm looking for. I've tried Apple's sample but it is just colors and I don't know how to make it views. All I'm looking for is a screen that will page while showing the page control. Each time the scroll view pages i want it to show a completely different view. Not different text or images but a different view. A lot like the home screen of the iPhone or ESPN Scorecenter app. Please Help!
Thank you.
I created this universal solution as examples found was to complicated and this is readable for me, code should be self explanatory.
- (IBAction)changePage:(id)sender {
_pageControlUsed = YES;
CGFloat pageWidth = _scrollView.contentSize.width /_pageControl.numberOfPages;
CGFloat x = _pageControl.currentPage * pageWidth;
[_scrollView scrollRectToVisible:CGRectMake(x, 0, pageWidth, _scrollView.frame.size.height) animated:YES];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
_pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (!_pageControlUsed)
_pageControl.currentPage = lround(_scrollView.contentOffset.x /
(_scrollView.contentSize.width / _pageControl.numberOfPages));
}
This does the same as #ReneDohan answer without the need for variable to store state
- (IBAction)changePage:(id)sender {
CGFloat x = self.pageControl.currentPage * self.scrollView.frame.size.width;
[self.scrollView setContentOffset:CGPointMake(x, 0) animated:YES];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.isDragging || scrollView.isDecelerating){
self.pageControl.currentPage = lround(self.scrollView.contentOffset.x / (self.scrollView.contentSize.width / self.pageControl.numberOfPages));
}
}
Try out this framework : https://github.com/AdrianFlorian/AFImageViewer to present images in a scroll view using a page controll to indicate the current page.
I have't added documentation yet, but you can see examples if you clone the project.
You can easily:
- download images from the internet in a separate thread by only giving an array of urls (image urls)
- give it an array of UIImage objects
- implement a delegate and manage the image for each page yourself
There is a related question: How do I use UIPageControl to create multiple views?, a really good way to do that is explained in this blog post: http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html.
I've made a demo project for this question. Please visit:
https://github.com/lenhhoxung86/PageControlDemo