Ok, this might seem like a simple thing to do – and in most cases it is, unless you’re using core data and have some row additions coming in dynamically.
You see the problem I had was, that row zero is white, row one is blue, row two is white….etc, and when I synced with my remote server and new data arrived, it was inserted at row zero - which is white! The other rows were pushed down, so row zero and row one were both white! No more alternate. I could have just refreshed the UITableView – or the visible rows, but I didn’t want to do that! I wanted it to figure out the correct row colour from the insert.
I got it working by combining the row index with the total rows, using the inverse of one and XOR’ing the result! Sounds complicated? Look at this table:
A: Row
B: Row Modulus (%2)
C: Row Count
D: Count Modulus (%2)
E: Inverse Count Modulus
F: XOR B ^ E
0
0
6
0
1
1
1
1
6
0
1
0
2
0
6
0
1
1
3
1
6
0
1
0
4
0
6
0
1
1
5
1
6
0
1
0
As can be seen above, I can get alternate row colours from Column B or Column F. However, if you then add another row at index zero – the row modulus can no longer be used, but Column F, still preserves the alternate row colours!
CodeSign error: Code Signing Identity ‘iPhone Distribution: XXXXX’ does not match any code-signing certificate in your keychain.
I’ve been getting this intermittent issue from our Bamboo build server, which builds our iOS project using xcodebuild. It seems to resolve itself after a restart of the mac, however.. a few builds later and it fails again. We’re using XCode 4.1 on OS X Lion 10.7.1.
I inserted this into the build script
security list-keychains
..and I can see that Bamboo has access to the login and the System keychains
Listing the current keychains
08-Sep-2011 12:43:26
“/Users/mac0004/Library/Keychains/login.keychain”
08-Sep-2011 12:43:26
“/Library/Keychains/System.keychain”
….however, after a few builds (and something else that I don’t know what happens), this command reports
Listing the current keychains
08-Sep-2011 13:23:16
“/Library/Keychains/System.keychain”
08-Sep-2011 13:23:16
“/Library/Keychains/System.keychain”
It’s strange how it reports the System.keychain twice, and that it can no longer find the login keychain.
Anyway, the solution for me was to copy/move my iOS certificates to the System.keychain.
I also had another error: ‘CSSM_ERRCODE_INTERNAL_ERROR’, which I resolved by installing the intermediate certificate from Apple again. You can get this from the provisioning portal, certificates section. Or from this link: Apple WWDRCA Intermediate Certificate
If you have similar problems and this doesn’t resolve it, post a comment.
Flickr Gallery turns your iPad into a digital photo frame using photos from one of the
biggest photo hosting sites on the net.
Flickr hosts more than 5 billion images and you can access these from Flickr Gallery.
NO FLICKR ACCOUNT NECESSARY
You don’t need an account with Flickr, as Flickr Gallery will display todays most interesting
photos. You can sign into your account and display photos from your own photostream or your
favourite photos.
GALLERY SETTINGS
* choose from a variety of photo transitions,
* the duration between photos,
* whether you want to see the photo title
* if you want to prevent the iPad from sleeping
* photos are high quality but you can choose medium quality to minimise data usage
PHOTO DETAILS
Touch the photo to bring up information about it and save it to your favourites or view it on
flickr’s website.
MORE…
Flickr Gallery has only just started development in June 2011. This is this intial release to
get it into your hands sooner. We are currently developing more features, such as a photo browser
and a flickr exploration browser. We also want to hear from the users – so let us know what you
want to see and we will strive to add it into an upcoming release.
Flickr Gallery turns your iPad into a Digital Photo Frame using photos from one of the biggest photo hosting sites on the web. Flickr hosts more than 5 billion images and you can access these easily from Flickr Gallery. You DONT need a flickr account – as it will default to interesting public photos. If you do have an account, you can login and display photos from your own photostream.
UITextView has square edges, and looks ugly compared to a UITextField!
Unfortunately, there isn’t an option to give the UITextView a nice border. There are various ways to do this, such as creating your own background image for the UITextView, but I have found a relatively easy way to do it – and one that anyone without photoshop skills can achieve.
I achieve it by placing a UITextField behind the UITextView. However, in InterfaceBuilder you can’t change the height of a UITextField, so you have to edit the .xib file in Text Edit to change its height.
Here are the steps you need to do:
Add a UITextField to your View and put a UITextView on top of it.
Decide on how high you want your UITextView and resize it.
Give the UITextField a tag of 999 (or whatever you want) (hit CMD-1 to bring up the attributes inspector to do this).
Save the .xib file and then right click the file > Open With > Other > TextEdit
Search for your tag, 999, and in the same
You need to change 31 to the same height as your UITextView and then save the .xib file in TextEdit
When you return to IB it will tell you the document has been modified, click Revert
You should now see a tall UITextField behind your UITextView. Make sure your UITextView has a transparent background!
<object class="IBUITextField" id="154341485">
<reference key="NSNextResponder" ref="774585933"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{25, 199}, {275, 31}}</string> THIS IS THE LINE THAT YOU NEED TO EDIT.... CHANGE 31 TO THE HEIGHT OF YOUR UITEXTVIEW
<reference key="NSSuperview" ref="774585933"/>
<reference key="IBUIBackgroundColor" ref="157267157"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<int key="IBUITag">999</int>THIS IS THE TAG YOU CHOSE TO HELP YOU FIND THIS SECTION IN THE XIB FILE
Here is my project if you need help seeing how I did it.
When you develop forms or any screens with input fields, occasionally the inputs will be obscured by the keyboard when it appears. This is bad usability for the user who now has to input data without being able to see what they have typed! One solution is to slide the whole view so that the field being edited is always visible.
This solution I provide adds a few methods to UIView (yes i know, adding categories to cocoa classes is naughty) – which will determine how much to slide the view based on the inputs position on the whole screen, and then slide the view at the same speed as the keyboard slide entry. It then will slide back to where it was when you are finished editing.
It is pretty simple to do this – here is how I calculate where to scroll the view:
- (void) maintainVisibityOfControl:(UIControl *)control offset:(float)offset {
static const float deviceHeight = 480;
static const float keyboardHeight = 216;
static const float gap = 5; //gap between the top of keyboard and the control
//Find the controls absolute position in the 320*480 window - it could be nested in other views
CGPoint absolute = [control.superview convertPoint:control.frame.origin toView:nil];
//If it would be hidden behind the keyboard....
if (absolute.y > (keyboardHeight + gap)) {
//Shift the view
float shiftBy = (deviceHeight - absolute.y) - (deviceHeight - keyboardHeight - gap - offset);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f]; //this is speed of keyboard
CGAffineTransform slideTransform = CGAffineTransformMakeTranslation(0.0, shiftBy);
self.transform = slideTransform;
[UIView commitAnimations];
}
}
You only need to make minimal changes to your own code, and call these methods from your UITextFieldDelegate methods (or other control delegates):
- (void) textFieldDidBeginEditing:(UITextField *)textField {
[self.view maintainVisibityOfControl:textField offset:0.0f];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == currentControl) {
//If the textfield is still the same one, we can reset the view animated
[self.view resetViewToIdentityTransform];
}else {
//However, if the currentControl has changed - that indicates the user has
//gone into another control - so don't reset view, otherwise animations jump around
}
}
UPDATE: iOS 4.1 Now has this behaviour built into the SDK. You can set your keyboard type to be UIKeyboardTypeDecimalPad ! Finally !
Of the various keyboards you can choose when developing iPhone apps, the number pad doesn’t come with a decimal point. There is a blank button in the bottom left corner that doesn’t do anything, so I’m going to show you how to put a decimal point button there to look like this:
There are a few other tutorial around that show you how to do this, but i believe mine is better….because the code is simpler to use, its more flexible, and the UI colors and button states are perfectly matched to the rest of the keyboard (unlike some of the other tutorials) The code you use to implement this will look like this:
it works on any number of UITextFields that are displayed on your view controller.
It will only add one decimal point per text field.
To achieve this, here are the basic steps of what i do:
Create a custom UIButton with clear background and dark grey text.
For the highlighted state i change the background image of the button and the text color to be white
I find the UIKeyboard in the application window and add the custom button at the required location
I add a delegate to the button to listen for click events and pass the event to a handler which adds a decimal point to the current UITextField
Update 5th June 2010: OS4 compatible and using only public API
As using private API’s is against the SDK agreement, I’ve updated the code to remove references to any private API. It is also now compatible with OS 4.0.
Update 20th July 2010: This code was part of the app I’m working on and was accepted by apple.
Here i will show you how to animate an object along a path on a UIView. I will create the path and draw it onto the UIView so that you can see it, and then use the same path for the animation.
I’m doing all of this within a UIView that i have added to my screen…
Firstly, we will draw a curved line on the screen….
//This draws a quadratic bezier curved line right across the screen
- ( void ) drawACurvedLine {
//Create a bitmap graphics context, you will later get a UIImage from this
UIGraphicsBeginImageContext(CGSizeMake(320,460));
CGContextRef ctx = UIGraphicsGetCurrentContext();
//Set variables in the context for drawing
CGContextSetLineWidth(ctx, 1.5);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
//Set the start point of your drawing
CGContextMoveToPoint(ctx, 10, 10);
//The end point of the line is 310,450 .... i'm also setting a reference point of 10,450
//A quadratic bezier curve is drawn using these coordinates - experiment and see the results.
CGContextAddQuadCurveToPoint(ctx, 10, 450, 310, 450);
//Add another curve, the opposite of the above - finishing back where we started
CGContextAddQuadCurveToPoint(ctx, 310, 10, 10, 10);
//Draw the line
CGContextDrawPath(ctx, kCGPathStroke);
//Get a UIImage from the current bitmap context we created at the start and then end the image context
UIImage *curve = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//With the image, we need a UIImageView
UIImageView *curveView = [[UIImageView alloc] initWithImage:curve];
//Set the frame of the view - which is used to position it when we add it to our current UIView
curveView.frame = CGRectMake(1, 1, 320, 460);
curveView.backgroundColor = [UIColor clearColor];
[self addSubview:curveView];
}
Now we will create a keyframe animation, and a path that is the same as the line we just drew. We will also draw a circle, and animate it along that path:
- (void) animateCicleAlongPath {
//Prepare the animation - we use keyframe animation for animations of this complexity
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//Set some variables on the animation
pathAnimation.calculationMode = kCAAnimationPaced;
//We want the animation to persist - not so important in this case - but kept for clarity
//If we animated something from left to right - and we wanted it to stay in the new position,
//then we would need these parameters
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = 5.0;
//Lets loop continuously for the demonstration
pathAnimation.repeatCount = 1000;
//Setup the path for the animation - this is very similar as the code the draw the line
//instead of drawing to the graphics context, instead we draw lines on a CGPathRef
CGPoint endPoint = CGPointMake(310, 450);
CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath, NULL, 10, 10);
CGPathAddQuadCurveToPoint(curvedPath, NULL, 10, 450, 310, 450);
CGPathAddQuadCurveToPoint(curvedPath, NULL, 310, 10, 10, 10);
//Now we have the path, we tell the animation we want to use this path - then we release the path
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
//We will now draw a circle at the start of the path which we will animate to follow the path
//We use the same technique as before to draw to a bitmap context and then eventually create
//a UIImageView which we add to our view
UIGraphicsBeginImageContext(CGSizeMake(20,20));
CGContextRef ctx = UIGraphicsGetCurrentContext();
//Set context variables
CGContextSetLineWidth(ctx, 1.5);
CGContextSetFillColorWithColor(ctx, [UIColor greenColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
//Draw a circle - and paint it with a different outline (white) and fill color (green)
CGContextAddEllipseInRect(ctx, CGRectMake(1, 1, 18, 18));
CGContextDrawPath(ctx, kCGPathFillStroke);
UIImage *circle = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *circleView = [[UIImageView alloc] initWithImage:circle];
circleView.frame = CGRectMake(1, 1, 20, 20);
[self addSubview:circleView];
//Add the animation to the circleView - once you add the animation to the layer, the animation starts
[circleView.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];
}
To get all this running, you can use this init method:
I’m sure there are lots of better ways of doing this, such as using CALayers and adding CGImage to the layers. But that’s something I haven’t tried yet. The example above should be enough to get you started with animation along a path.
Doing some iPhone development and this error really caught me out for a while:
2009-11-16 21:02:48.387 Pickers[3779:207] *** Terminating app due to uncaught
exception 'NSUnknownKeyException', reason: '[<UIViewController 0x381d740>
setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key datePicker.'
2009-11-16 21:02:48.388 Pickers[3779:207] Stack: (
It’s seemed fairly cryptic at the time. I had created a Tab Bar Controller and for each tab button, i hadn’t set its class identity – so each tab was still declared as a UIViewController instead of the actual Controller class that i had created.
The error comes from the NSKeyValueCoding category which allows you to access properties via setValue: forKey:
Person *aPerson = [[Person alloc] initWithAge: 53];
aPerson.name = @"Steve";
// NOTE: dot notation, uses synthesized setter, equivalent to [aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@),
property name(%@) and direct instance variable access (%@)",
[aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);
So i guess it is just complaining that it can’t find the generated setter method named setDatePicker – because datePicker instance is not on the generic class.