One of the ways to improve user experience in iOS while showing images is to download them asynchronously without blocking the main thread and showing them....
But I want to add something to this -
Initially when there is no image,show a spinner while the async download has started.
After the download cache the image on local iOS disk for later use.
After the download populate the image part of UIImageView.
And dont just plonk the image into view for user. Showly Fade in the user (i.e. from alpha 0.0 to 1.0)
I have been using SDWebImage for sometime now. It works well but does not satisfy my 1st requirement (about spinner) and 4th.
Is there any help out there to satisfy all this?
Three20 http://www.three20.info has a TTImageView class that statisfies 2-3, you can subclass it and overwrite setImage: and create the fade animation there. (or just modify TTImageView.m directly).
Spinner is easy as well when you modify TTImageView you can add a TTActivityView on top and remove it on setImage:
Related
I have tiny issue in my app. I load data from JSON and then take image links and load images on cells. Im not sure i really should paste all of my code, since it may not concern the issue. Just want to point i use
[imageView setImageWithURL:url];
and in myCell custom class i use:
- (void)prepareForReuse {
[self.myCellImageView cancelImageRequestOperation];
self.myCellImageView.image = nil;
}
Second code snipper fix the issue when u smoothly scroll table, tableView load correct images. But there is the trick - if u press on status bar on an iPhone (place where your clock, battery charge and carrier name appears) you may get from bottom of your table to top in fraction of second.
During that, application proceed to load wrong images (apparently, recently loaded in bottom cells), and after switching images it set correct one.
I want to admit, that problem almost didn't noticeable if u scrolling with low or medium speed, it only appears when you make enormous move from one side of tableView to another. But still, its nasty bug. How could i fix it?
Thanks!
I am developing an universal app where I have given a background image for a UIView using the following code.
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"backImage.png"];
[self.view addSubview:imgView];
[self.view sendSubviewToBack:imgView];
I have created the following images and added to the project,
backImage.png
backImage#2x.png
backImage-Portrait~ipad.png
backImage-Portrait#2x~ipad.png
backImage-Landscape~ipad.png
backImage-Landscape#2x~ipad.png
But it does not seem to take the correct images.
It works fine when I run the app on iphone (I mean it takes the backImage.png and backImage#2x.png accordingly) but when I run the app on ipad it does not use the ipad images, it still uses the iphone images.
Can anyone please tell what must be going wrong.
Thanks in advance.
You need to detect in your code what type of device is being used, and depending on that, choose the appropriate image.
See here: iOS detect if user is on an iPad
I may be wrong, but I don’t think UIImage will know whether to load the ‘portrait' or ‘landscape' version of an image, much less change them dynamically when you rotate your interface. I think you’re expecting a lot more magic then there is.
Those conventions work in the app launch snapshot, but I think that’s the extent of it?
am working on an app where i am loading one image from the bundle and with the help of quartz i am adding two red circles on that image, the image is loaded in the instance of the UIImageVIew class.
I want to save the image with the red circle, so far i have found only one method and thats
UIImageWriteToSavedPhotosAlbum(UIImage * image,id completionTarget,SEL completionSelector, void * contextInfo)
but its not working as it is saving the image from the bundle only, in some post i have read that it can be done using CALayer but i found no useful link to do that, i would be glad if you can post me the answer or any tutorial link to do that.
Here's a trick! Refer to Capture UIView here, you can capture the UIImageView snapshot and save it using UIImageWriteToSavedPhotosAlbum.
I'm currently using an AVPlayer, along with an AVPlayerLayer to play back some video. While playing back the video, I've registered for time updates every 30th of a second during the video. This is used to draw a graph of the acceleration at that point in the video, and have it update along with the video. The graph is using the CMTime from the video, so if I skip to a different portion of the video, the graph immediately represents that point in time in the video with no extra work.
Anywho, as far as I'm aware, if I want to get an interface similar to what the MediaPlayer framework offers, I'm going to have to do that myself.
What I'm wondering is, is there a way to use my AVPlayer with the MediaPlayer framework? (Not that I can see.) Or, is there a way to register for incremental time updates with the MediaPlayer framework.
My code, if anyone is interested, follows :
[moviePlayer addPeriodicTimeObserverForInterval: CMTimeMake(1, 30) queue: dispatch_queue_create("eventQueue", NULL) usingBlock: ^(CMTime time) {
loopCount = (int)(CMTimeGetSeconds(time) * 30);
if(loopCount < [dataPointArray count]) {
dispatch_sync(dispatch_get_main_queue(), ^{
[graphLayer setNeedsDisplay];
});
}
}];
Thanks!
If you're talking about the window chrome displayed by MPMoviePlayer then I'm afraid you are looking at creating this UI yourself.
AFAIK there is no way of achieving the timing behaviour you need using the MediaPlayer framework, which is very much a simple "play some media" framework. You're doing the right thing by using AVFoundation.
Which leaves you needing to create the UI yourself. My suggestion would be to start with a XIB file to create the general layout; toolbar at the top with a done button, a large view that represents a custom playback view (using your AVPlayerLayer) and a separate view to contain your controls.
You'll need to write some custom controller code to automatically show/hide the playback controls and toolbar as needed if you want to simulate the MPMoviePlayer UI.
You can use https://bitbucket.org/brentsimmons/ngmovieplayer as a starting point (if it existed at the time you asked).
From the project page: "Replicates much of the behavior of MPMoviePlayerViewController -- but uses AVFoundation."
You might want to look for AVSynchronizedLayer class. I don't think there's a lot in the official programming guide. You can find bits of info here and there: subfurther, Otter Software.
In O'Really Programming iOS 4 (or 5) there's also a short reference on how to let a square move/stop along a line in synch with the animation.
Another demo (not a lot of code) is shown during WWDC 2011 session Working with Media in AV Foundation.
I'm coding an application on Ipad, in a certain point of my application I present a ViewController with the presentModalViewController.
My ViewController is a UISScrollView who take the larger of the modalView and inside it I display some images, I allow pagingEnabled so I can see all my images inside the scrollView.
Sometimes I have to display more than 10 images inside the scrollView, so I have this error
RECEIVE MEMORY WARNING LEVEL=1 after this one RECEIVE MEMORY WARNING LEVEL=2 and finnaly the debugger exited due to signal 10 (Sigbus).
What can I do? is there a way to unload the image thats offscreen? or others things to do?
Thanks,
I guess you're adding all the images to the UIScrollView? Then the iPad has to keep all 10 images in memory. If they are full screen images, each of them will take up about 3 MB of memory, so you're using 30MB just to keep the 10 images in the scroll view.
You should only add the one or two images that are actually visible. Once they scroll out of sight, remove the UIImageView from your UIScrollView (and make sure you don't retain it anywhere else so it can be deallocated). When a new image scrolls into sight, add it to the UIScrollView only then.
In your UIScrollViewDelegate method -scrollViewDidScroll: get the current contentOffset and use that to calculate which images are visible.
Actually, this problem is even worse on the iPhone 3G, which can't even manage to display two full size photos (taken with it's own camera) at the same time.
If you can make the photos smaller ahead of time by resizing them (server side if you're snagging them from your own services, or client side if they're somehow generated on the device or retrieved from third party services), you should. They will load faster, and you can put more of them on the screen at once without running into memory issues.
The Three20 library has a really great photo-browsing control for the iPhone. I'm pretty sure they only have three photos around at any given time... the photo you're looking at, and the photos going forward or backwards.
http://github.com/facebook/three20
I also think there is an iPad branch of the Three20 controls (at ./tree/ipad), although I don't know if they include the photo browser or not, and haven't tried them yet myself... maybe that's an option for you if you don't want to spend a lot of time on that particular feature of your application. If the iPad photo browser isn't done maybe you could just adapt the iPhone version to suit your needs (shouldn't be hard).
If you want to bake the feature yourself, I'd take some inspiration from the UITableViewController. Your controller should come with associated datasource and delegate protocols to retrieve photos and respond to user events. The controller base class itself should reuse three UIImageViews and should shuffle those around to create the illusion that the user is scrolling through a large list.