В связи с тем, что Apple вчера начала отклонять приложения, которые используют уникальный идентификатор устройства (UDID), возникает вопрос - чем же можно заменить UDID? Ведь очень часто при разработке приложений, которые используют в своей работе веб-сервисы, нам необходимо знать с какого устройства пришел тот или иной запрос.
На мой взгляд наиболее эффективной заменой UDID будет один из описанных ниже способов.
As most of you probably know, UITableView’s are incredibly useful and versatile views to be using in your applications.
If you have ever tried to customize a UITableView though, you know that as soon as you start adding lots of UIViews, UILabels, and UImageViews to a cells ContentView, that these tableviews start to scroll slower and slower, and become choppier and choppier.
What we are going to explore today is how to remedy that situation.
To download the entire XCode project, you can find it at:
We are going to build a simple contact viewer, that will display the phones contacts. For each contact, if they have a first name, last name, email and phone number, they will be displayed within one cell, with different colors. The reason this is useful is because it provides the basics for customizing UITableViewCells that can really start to make your application look nice, and still scroll well.
In this example, we have a standard UITableViewController. We are going to have a couple class variables defined in the header
ABAddressBookRef _addressBook is defined in our header, so that we don’t have to release it until we dealloc. And the contacts is so that we can hold on to the data for our tableView.
In the main table view controller file we are going to override the – (void)viewDidLoad to provide some initial configuration of the tableView, as well as loading or generating our data. (We will generate fake data for devices or the simulator that don’t have address book data)
As you can see here we have a couple of self.tableView methods we have called to setup the background color, and also the cell separator style.
If you are running this application on a device, or simulator that has contacts, this method will also make a copy of the address book as the data to display. If there is no data in the address book, we create some fake test data just for displaying.
Also don’t forget to include our – (void)dealloc method for releasing our _addressBook variable.
The next portion we have to override is the – (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath so that we can supply the tableView with our cells.
Some tutorials will have you put this next part into a separate UIView subclass, and add that class as the contentView of this UITableViewCell, but I prefer to override the drawRect of the UITableViewCell, and do all my drawing there.
The first thing I am doing is getting the current graphics context so that we can draw to the screen, clipping to the rect that is passed in drawRect:(CGRect)rect, and then depending on whether this cell is even, I am filling the entire rect with an almost black color, or slightly lighter.
The next thing I am going to figure out is whether I want this text to be centered in the cell, and I am determining this based off whether there is an email field or not.
//Vertically center our text, if no emailBOOL isCentered =(self.email ==nil);
And now for the meat of the drawRect method. We calculate the size of firstName, draw it offset from the left by 5, and then draw lastName right after it. We also change the color we are drawing between those two.
Next we find out if phone actually exists, and if so set the color to red, and draw it to the right of lastName. We also have to make sure we aren’t drawing this outside our boundaries, so we check to see where the end is, and if it is outside, we crop it to 5 pixels from the end.
if(self.phone !=nil){[[UIColor redColor] set];
size =[self.phone sizeWithFont:defaultFont];
CGFloat end = CGRectGetMaxX(tempRect)+ size.width;
if(end > rect.size.width){
size.width = CGRectGetMaxX(rect)- CGRectGetMaxX(tempRect)-10; //-10 so that we get 5 from the end of last name, and 5 from the end of rect}if(isCentered ==NO){
tempRect = CGRectMake(CGRectGetMaxX(rect)- size.width -5, 0, size.width, size.height);
}else{
tempRect = CGRectMake(CGRectGetMaxX(rect)- size.width -5, midY - size.height/2, size.width, size.height);
}[self.phone drawInRect:tempRect withFont:defaultFont lineBreakMode:UILineBreakModeTailTruncation];
}
And finally if our email actually exists draw it on the bottom left.
Sometimes you might want to retrieve certain properties from an image file, such as the image’s dimensions or other metadata, without actually displaying the full-size image on screen. The simplest way to do that on iOS is using the class:
The problem with this approach is that the entire image gets loaded into memory. And since the pixel data is stored uncompressed in memory, even a small 512 ? 512 image (that fills less than half of an iPhone 4’s screen) will take up 1 MB of memory.
CGImageSource
As of iOS 4, the SDK includes a better solution in the form of the set of functions, which have been available on the Mac since forever. These functions allow you to access certain image metadata without having to load the actual pixel data into memory. For example, getting the pixel dimensions works like this (make sure to include the ImageIO.framework in your target):
#import <ImageIO/ImageIO.h>NSURL*imageFileURL=[NSURLfileURLWithPath:...];CGImageSourceRefimageSource=CGImageSourceCreateWithURL((CFURLRef)imageFileURL,NULL);if(imageSource==NULL){// Error loading image...return;}NSDictionary*options=[NSDictionarydictionaryWithObjectsAndKeys:[NSNumbernumberWithBool:NO],(NSString*)kCGImageSourceShouldCache,nil];CFDictionaryRefimageProperties=CGImageSourceCopyPropertiesAtIndex(imageSource,0,(CFDictionaryRef)options);if(imageProperties){NSNumber*width=(NSNumber*)CFDictionaryGetValue(imageProperties,kCGImagePropertyPixelWidth);NSNumber*height=(NSNumber*)CFDictionaryGetValue(imageProperties,kCGImagePropertyPixelHeight);NSLog(@"Image dimensions: %@ x %@ px",width,height);CFRelease(imageProperties);}
All the Metadata You Dreamed Of
The dictionary returned by CGImageSourceCopyPropertiesAtIndex() contains a lot more than just the image dimensions. If present, it includes the complete and metadata and also various file-format-specific information for TIFF, GIF, JPEG, PNG and Raw files (among others).
As an example, let’s read out the date a photo was taken, the model name of the camera and the GPS coordinates stored in the metadata:
This produces the following output on my sample image:
Date Taken: 2011:03:27 11:30:30
Camera Model: Canon EOS 20D
GPS Coordinates: 8.374788 E / 54.89472 N
An NSLog(@"Image properties: %@", (NSDictionary *)imageProperties); will quickly show you all the available metadata for a particular image. It’s fun to experiment with different files. The documentation lists all available metadata keys at .
Recent Comments