问题
I want photo slider like whts app has. It should access all the pics or some of the pics from in build photo library and it should be scrollable using scroll view.
I have tried with different photo viewer but everything has memory issue. So not sure if anyone has it's working solution. Really appreciate your help.
Thank you,
Ankita
回答1:
This is working almost fine, but one small problem with backbord direction scrolling. Just try this out may be you can find some direction to go and may be find better solution using it.
(Have used ELCImagePicker to show first time all images and then on selecting one present the scrollview to show large images at a time 10 images are shown also have tweak the delegate method of ELCImagePickerController to get the index of selected image)
At first load ie when select image from ELCImagePickerController
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info selectedIndex:(NSInteger)_index {
[self dismissModalViewControllerAnimated:NO];
for (UIView *v in [scrollview subviews]) {
[v removeFromSuperview];
}
infoItems = [[NSArray alloc]initWithArray:info];
CGRect workingFrame = scrollview.frame;
workingFrame.origin.x = 0;
int indexFrame = picker.selectedIndex;
newIndex = indexFrame;
for(int i = 0; i < [info count]; i++)
{
NSDictionary *dict = [info objectAtIndex:i];
UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
imageview.tag = i;
if(i >= indexFrame && i <= indexFrame + 9)
{
[scrollview addSubview:imageview];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
}
}
[scrollview setPagingEnabled:YES];
[scrollview setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
[scrollview scrollRectToVisible:CGRectMake(0, 0, workingFrame.size.width, workingFrame.size.height) animated:NO];
self.scrollview.hidden = NO;
self.pageControll.hidden = NO;
self.pageControll.numberOfPages = [[scrollview subviews]count];
index = 0;
lastContentOffset = scrollview.contentOffset.x;
NSLog(@"lastContentOffset %.2f",lastContentOffset);
}
After that on scrollViews delegate method
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(@"ScrollViewDidEndDecelerating is called with subview(s) %d",[[scrollview subviews]count]);
if(lastContentOffset < scrollView.contentOffset.x)
{
index += (int)(scrollview.contentOffset.x - lastContentOffset)/scrollview.frame.size.width;
newIndex += (int)(scrollview.contentOffset.x - lastContentOffset)/scrollview.frame.size.width;
self.pageControll.currentPage = index;
NSLog(@"Index incremented %d \n newIndex %d",index,newIndex);
if(index == [[scrollView subviews]count]-1)
{
if(newIndex < [infoItems count]-1)
{
[self performSelector:@selector(reloadScrollViewWithNewImages)];
}
}
[Appirater userDidSignificantEvent:YES];
}
else if(lastContentOffset > scrollView.contentOffset.x)
{
index -= (int)(lastContentOffset - scrollview.contentOffset.x)/scrollview.frame.size.width;
newIndex -= (int)(int)(lastContentOffset - scrollview.contentOffset.x)/scrollview.frame.size.width;
self.pageControll.currentPage = index;
NSLog(@"Index decremented %d \n newIndex %d",index,newIndex);
if(index == 0)
{
if(newIndex > 0)
{
newIndex -= 9;
if(newIndex < 0)
newIndex = 0;
[self performSelector:@selector(reloadScrollViewWithNewImages)];
}
}
[Appirater userDidSignificantEvent:YES];
}
lastContentOffset = scrollView.contentOffset.x;
NSLog(@"New lastContentOffset %.2f",lastContentOffset);
}
and the method used for reload the scrollView is as follow
-(void)reloadScrollViewWithNewImages
{
for (UIView *v in [scrollview subviews]) {
[v removeFromSuperview];
}
CGRect workingFrame = scrollview.frame;
workingFrame.origin.x = 0;
NSLog(@"reloadScrollView newIndex %d",newIndex);
int indexFrame = newIndex;
for(int i = 0; i < [infoItems count]; i++)
{
NSDictionary *dict = [infoItems objectAtIndex:i];
UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
imageview.tag = i;
if(i >= indexFrame && i <= indexFrame + 9)
{
[scrollview addSubview:imageview];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
}
}
[scrollview setPagingEnabled:YES];
[scrollview setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
[scrollview scrollRectToVisible:CGRectMake(0, 0, workingFrame.size.width, workingFrame.size.height) animated:NO];
self.scrollview.hidden = NO;
self.pageControll.hidden = NO;
index = 0;
self.pageControll.numberOfPages = [[scrollview subviews]count];
NSLog(@"number %d",[[scrollview subviews]count]);
lastContentOffset = scrollview.contentOffset.x;
NSLog(@"reloadScrollView's lastContentOffset %.2f",lastContentOffset);
}
and all used properties and private ivars declared in .h file's interface part required in this code are
Private ivars
NSInteger index;
float lastContentOffset;
Properties
@property (nonatomic,strong) IBOutlet UIScrollView *scrollview;
@property (strong, nonatomic) NSArray *infoItems;
@property (assign, atomic) int newIndex;
Happy Coding :)
回答2:
You can use CATiledLayer to draw image. CATiledLayer can be used to increase the performance of paging, panning, and zooming with high-resolution images or large sets of photos.
As i commented above you can go by reusable view approach means at a time only three imagview or view will be in memory. Let say you are showing photo number:2 so, you should have to keep photo:1,2 and3 in memory(i.e. to avoid flicker) no need to load all photos at a time. Suppose you are scrolling to photo number:3 then your logic should discard photo number:1 and should load photo number:2,3,4. If you are still not getting or don't know how to do this programmatically then don't worry. Apple's good sample code is available that is doing all you want.
Sample code
In above sample code they have displayed two way of displaying image.
One is directly showing/setting the image into image view.
Second is with drawing image with TileView using this method:- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize
If you are thinking lot of about memory then definitely you have to use second approach.
来源:https://stackoverflow.com/questions/11758454/need-to-create-photo-slider-using-photo-library-photos-in-iphone