590Adding an UIAlertView
Unlike other UIViews, UIAlertView does not need to be added to another view via addSubView. [myAlertView show] takes care of that.
Trivial, maybe. But I wasn't aware of it.
Unlike other UIViews, UIAlertView does not need to be added to another view via addSubView. [myAlertView show] takes care of that.
Trivial, maybe. But I wasn't aware of it.
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Hello"
message:@"Do you really want to?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
The intuively unobvious thing is, that otherButtonTitles requires a nil-terminated, comma-seperated list(?) of NSStrings.
Although you can add (any number?) of additional buttons, it gets silly after about 3.
Another thing to note is that in the case of two buttons, they get displayed side by side, whereas one button or more than two are shown vertically stacked.
Nice and simple Category to resize an UIImage
@interface UIImage (Resize)
- (UIImage*)scaleToSize:(CGSize)size;
@end
#import "UIImageResize.h"
#import
@implementation UIImage (Resize)
- (UIImage*)scaleToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
@end
NSDictionary
arrayKey
string1
string2
string3
string4
dicKey
key1
object1
key2
object2
key3
object3
key2
object2
key3
object3
NSArray
string1
string2
string3
key1
object1
key2
object2
key3
object3
string5
At the end, after </plist>, there's another CR.
Combining two images, especially useful, if the overlay image has an alpha value:
//
// UIImage+Category.h
// ImageOverlay
//
// Created by Georg Tremmel on 29/04/2010.
//
#import
@interface UIImage (combine)
- (UIImage*)overlayWith:(UIImage*)overlayImage;
@end
And the implementation file.
//
// UIImage+Category.m
// ImageOverlay
//
// Created by Georg Tremmel on 29/04/2010.
//
#import "UIImage+Category.h"
@implementation UIImage (combine)
- (UIImage*)overlayWith:(UIImage*)overlayImage {
// size is taken from the background image
UIGraphicsBeginImageContext(self.size);
[self drawAtPoint:CGPointZero];
[overlayImage drawAtPoint:CGPointZero];
/*
// If Image Artifacts appear, replace the "overlayImage drawAtPoint" , method with the following
// Yes, it's a workaround, yes I filed a bug report
CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.999999999];
*/
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return combinedImage;
}
@end
An update to 334 Combining Images with UIImage & CGContext – (Offscreen drawing)
(Did I say, how much I love Categories...?)
Update I came across some strange behaviour when layering a PNG image with transparency over another image. Did not show up in the Simulator, only in iPhone 3GS (and probably also on other devices.) The base image draws fine, but the overlay image appears to be truncated and the last pixels shifted, producing some bright green artifacts. Changing
[overlayImage drawAtPoint:CGPointZero];
to
CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:1.0];
did not really help; the green artifacts remainded. It was strange though, that they did not appear in the other blendmodes. Using
CGContextDrawImage(c, imageRect, [overlayImage CGImage]);
would also work, but then the images turn up upside down. Not what I really needed. (Yes, I know, there might not be a hard fix for that, but really - it should be that complicated.)
After playing a bit more with the values, I found, that setting alpha lower than 1.0 gets rid of the display artifact:
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.9999999];
Bug filed at Apple's Bug Report, let's see. Or maybe am I missing something here?
Anyway here they the files are, zipped and ready for download.
Post Scriptum
Test Project, showing the visual artifact in action. Only appears on the device, NOT IN THE SIMULATOR.
Writing
CFStringRef textColorKey = CFSTR("defaultTextColor");
CFStringRef colorBLUE = CFSTR("BLUE");
CFPreferencesSetAppValue(textColorKey, colorBLUE, kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
Reading
CFStringRef textColorKey2 = CFSTR("defaultTextColor");
CFStringRef textColor;
textColor = (CFStringRef)CFPreferencesCopyAppValue(textColorKey2,kCFPreferencesCurrentApplication);
textColor must still be releasesed with CFRelease(textColor);
Side note As we should know by now, CFStringRef is a toll-free bridge to NSString, meaning it's possible to use a CFStringRef like a NSString.
NSLog(@"my CFStringRef %@", textColor);
NSString *stripped = [unstripped stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\n\t "]];
Well, Cocoa, a bit of too much syntactic nutrasweet here. Take a look at PHP and wheep:
$stripped = trim($unstripped);
(Yes, I am aware that's somewhat of an unfair comparion, but still...)
From NSData to NSString:
NSString *s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];
And the other way round:
NSData *d = [s dataUsingEncoding:NSUTF8StringEncoding]:
#import is identical to #include, except that it makes sure that the same file is never included more than once. It’s therefore preferred and is used in place of #include in code examples throughout Objective-C–based documentation.
http://developer.apple.com/ mac/library/documentation/ cocoa/conceptual/ObjectiveC /Articles/ ocDefiningClasses.html
Having previously done Core Animation only on the iPhone, I am still a beginner when it comes dealing with in on OSX.
The first thing that surprised me, is that layers have implicit animations; meaning whenever you change a value, the layer will animate to it using certain defaults. (duration = 0.25, etc.) While it is nice, I am still looking for a way to control it.
When you want to know, when an animation is finished, you need to make a CAAnimation, set the delegate and let it call animationDidStop:
CAAnimationGroup *group = [CAAnimationGroup animation];
group.delegate = self;
group.duration = 0.25;
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
CABasicAnimation *position = [CABasicAnimation animationWithKeyPath:@"position"];
position.fromValue = fromPointValue;
position.toValue = toPointValue;
CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacity.fromValue = [NSNumber numberWithFloat:1.0];
opacity.toValue = [NSNumber numberWithFloat:0.0];
group.animations = [NSArray arrayWithObjects:position, opacity, nil];
[removeTarget addAnimation:group forKey:@"group"];
While this animates nicely, it still is not quite right. Because the layer basically does not know, that it values are changed in the animation, and therefore, after the animation stopped, the values are reset to the ones BEFORE the animation.
That's the annoying snapback.
To get rid of it, tell the layer the new values, right after you add the animation.
removeTarget.opacity = 0.0;
removeTarget.position = toPointValue;
%nbsp;
Interesting to see, that others seem to go throught the same learning experience.