Edit mode for custom UITableViewCell with drawRect - iphone

I have a UITableViewCell subclass with this drawRect:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
if (self.checked)
{
[[UIImage imageNamed:#"checkMark.png"] drawInRect:CGRectMake([self.contentView bounds].origin.x + 10, 12.0, 22, 22)];
}
}
The problem occurs when the cell goes into edit mode and the drawn image doesn't move to the right like the UITextField and accessory views do. Instead the image becomes hidden by the delete button. How can I get the drawn image to animate to the right?
Thanks for your help.

You need your cell to redraw itself when entering editing mode. Usually all it will do is resize the content view, which won't cause your checkmark to be redrawn.
However, to animate this is a little harder since you are directly drawing the check mark. You could try directly drawing it in the content view instead, or adding a subview to the content view which contains the checkmark - this will get moved automatically.
You could even use the built in image view, it seems to be in approximately the right position?

Related

Avoid cell autoresizing in editing mode iPhone

I have a problem with my custom cells.
My cell is structured like this image:
Gray view = cell.contentView
Orange view = a button added as a subview to the contentView
Yellow view = a label added as subview to the contentView
Blue view = an image view added as subview to the contentView
Green view = accessory view
The problem is that when I toggle edit to tableView, my cell indents hiding accessory view and moving right everything else. I want to avoid this.
When I toggle editing mode, my cell mustn't move its content, the editing control (minus red button on the left) must take the place of the button inside the contentView and this last one should hide itself.
I tried tableView:shouldIndentWhileEditingRowAtIndexPath: method without success because my tableView is plain. I also tried to override willTransitionToState: method but I don't know how to do what I want.
Can someone help me?
Thank you so much!
How have you added the subviews to the cell? If you add them directly to the cell instead of adding them to the content view, they won't get moved. It is the content view that is resized when the cell transitions to editing mode.
If you want to hide certain subviews, you should override setEditing:animated: in the cell subclass and hide / show as appropriate.
You may also need to add your subviews such that they are below the contentView in the view hierarchy, or bring the content view to the top after you have finished, using the bringSubviewToFront: method.
If you really don’t want the cell to resize, you could implement -layoutSubviews thusly:
-(void)layoutSubviews
{
if ([self isEditing] == NO) {
// Lay out subviews normally.
}
}
When you go into edit mode, -layoutSubviews won’t follow the code path that lays out your views. This is assuming you’ve subclassed UITableViewCell.

iOS: Adding a fixed image just below the navigation bar

It feels like this should be fairly simple but nothing i've tried so far has worked. In a nutshell, I want to add a fixed image just below the navigation bar in a UITableViewController that i create programmatically. In other words, I want the image to stay just below the navigation bar even as the user scrolls up and down the table view (it's basically a custom drop-shadow for the navigation bar).
The closest I've gotten is the code below (in the UITableViewController's init method), which adds the image but doesn't keep it from moving when the user scrolls.
// Add nav bar drop shadow
UIImage *dropShadowImage = [UIImage imageNamed:#"NavBarDropShadow.png"];
UIImageView *dropShadowView = [[UIImageView alloc] initWithImage:dropShadowImage];
[self.view addSubview:dropShadowView];
Is there an easy way to add an add an image to the screen programmatically, position it wherever you like, and have it stay there even as the user scrolls? Thanks for any and all input!
EDIT: IOS5 has a better way to do this. Please check out the new UIAppearance protocol.
Adding this block of code to your code will allow you to draw your shadow on all UINavigationBars in the app. This is a better solution than adding the shadow as a UIImageView:
#implementation UINavigationBar (ShadowBar)
- (void)drawRect:(CGRect)rect {
//draw the shadow ui nav bar
UIImage *image = [UIImage imageNamed: #"UINavBarWithShadow.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
- (void)layoutSubviews {
self.frame = CGRectMake(0, 0, self.frame.size.width, 300);
}
#end
To make the UINavigationBar higher and thus not clipping your content, override the layoutSubviews and set the frame you need (the code above assumes your header is 300 points high). layoutSubviews does nothing by default, but is "lazy" called before lay-outing the view.
For more info about this custom size/look overrides that apply to UIView (and any other subclass) have a look here
You can make a subclass or a category on UINavigationBar, and have it add the image in the init or drawRect methods. If you think about it, you're trying to add a shadow to the navigation bar, not to the UITableView, so it makes sense to modify the navbar, not the table.
You are adding your dropShadowView to self.view that in your case is the view of an UITableViewController. It means that your self.view is an UITableView so when you scroll up and down you scroll the dropShadowView as well because is inside the tableView.
Try to write a custom UIViewController and add two subviews: one is the dropShadowView and the other one is your table.
Have a look at this similar question I answered a while back. It should do exactly what you want with little customization.
Transparent View at the Top of a UITableView
Dont make a UITableView the main view ie. the view outlet, set that to a UIView that contains a UITableView, then make your controller a subclass of UIViewController, and make it conform to UITableViewDataSource and UITableViewDelegate. in your nib, set up your view so that you have a UIImageView at the top and a UITableView below. and set the delegate and datasource to your file's owner.

UITableViewCell labels opaque=YES looks bad when clicking cell

I want my table cells to load fast, so I am setting all my UILabels inside my cell to be opaque=YES; This is fine, because I also set the backgrounds to white and it looks normal.
The problem comes when you click the cell, since the backgrounds of those labels are white, the blue selected color looks pretty bad when trying to highlight the cell. Is there a work around for this? Would setting the background color of those cells to clearColor just defeat the purpose of setting opaque?
There is something you have to consider. First, setting the labels to opaque is definitely the right way of getting good scrolling performance.
The proper way to do this is declaring a subclass of UITableViewCell and overwrite the setBackgroundColor method like this and forward the background color to each element of the cell:
- (void) setBackgroundColor:(UIColor *)color {
[super setBackgroundColor:color];
[titleLabel setBackgroundColor:color];
[imageView setBackgroundColor:color];
[timeLabel setBackgroundColor:color];
}
I used this as the file's Owner of the XIB where the tableview cell is defined and have connected the UI elements to outlets in this custom subclass.

Rotating UIView and still seeing the old position of the view

I am rotating a view using src.transform = CGAffineTransformMakeRotation(M_PI/2);, it is working well but I am still seeing the old position of the view (like that: http://cl.ly/233y403c2C1C451r1f28).
How can I refresh the view ? The view is in a UITableViewCell, I tried to refresh the row of the cell or even the tableview but it doesn't work.
Here is my drawRect method :
if (nil != _image) {
[_image drawInRect:rect contentMode:self.contentMode];
} else {
[_defaultImage drawInRect:rect contentMode:self.contentMode];
}
The view that I am rotating is embedded in a UIImageView which is part of the cell.
Thanks,
Martin
It sounds like you might have two copies of your image view there. When you rotate the top one, the bottom one is exposed.
What is the background colour of the UIView you're overriding drawRect in? Before drawRect is called, the background colour is applied to the context. Ensure you have a background colour set (i.e. not set to [UIColor clearColor], for example).
Also, what's the opaque property of your UIView set to?
If figured it out. I was trying to rotate the image while I was downloading it. When I rotate it from a delegate callback that is call when the image is loaded everything works fine.
All of that makes perfect sense !

How to scroll the content without scrolling the image in the background using UIScrollView?

I am trying to scroll the content without scrolling the image in the background using UIScrollView.
I am using IB and setting the FileOwner View to point to the Scroll View (Image View is a child of the Scroll view). I have made the image height to be 960 pixels.
I have also set scrolling content size in the vierController that owns this UIView
(void)viewDidLoad {
UIScrollView *tempScrollView = (UIScrollView *)self.view;
tempScrollView.contentSize=CGSizeMake(320, 960);
}
My problem is that the Image only appears moves along with the content.
I have tried taking out the settings in viewDidLoad, but the scrolling cease to function.
I have also tried changing the location of the image and have it placed under VIEW instead of Scoll View (by the way Scroll View is a child of VIEW), but that resulted in the app breaking (termination error).
Any advice would be appreciated.
The easiest (and correct way) is to set an background image to your UIScrollView
UIImage *img = [UIImage imageNamed:#"image.png"];
[scrollView setBackgroundColor:[UIColor colorWithPatternImage:img]];
The easiest way is to set an UIImageView behind your UIScrollView(UIImageView and UIScrollView under UIView) and make your UIScrollView background color as clear color as mentioned by Janson. By this way you can scroll the content without scrolling the image in the background using UIScrollView.
Thanks. This was extremely helpful.
The one thing that I would add (pardon if it is obvious, but for people new to the platform (i.e., me), it took a bit of playing around).
I put the code from "unset"'s example after where I setup the contentSize=CGSizeMake in the viewDidLoad of the UIViewController , i.e.,:
// Setup the Scroll View
UIScrollView *tempScrollView=(UIScrollView *)self.view;
tempScrollView.contentSize=CGSizeMake(320, 720);
// Set Stationary Background, so that while the user scroll the background is
// fixed.
UIImage *img = [UIImage imageNamed:#"bg-body.jpg"];
[tempScrollView setBackgroundColor:[UIColor colorWithPatternImage:img]];
Then, I went into the ViewController .xib file and on the UIView that is inside of the UIScrollView, I set the background color to "Clear Color".
I sure that there is a way to do this through code at the same time as setting the background of the UIScrollView, but at least that is how you can do it through IB.
Jason