UIImageView caching while tableviewcell height is reduced - iphone

I have UITableview which has custom cells with UIImageViews. In the UITableview I am increasing the height of the cell using didSelectRowAtIndexPath method. Also i am adding method to increase cell height and revert to normal height.
When i tap on the cell the height is increasing , when i tap on the cell again (in order to make the tableviewcell return to default height) while in transition the image which is on tableviewcell is stays like its shown below and goes back to default height ..(i dont know how the image is being displayed while in transition)
-(void) zoomOutProperties
{
fruitImage.frame=CGRectMake(0.0, 46.0, 320.0, 83.5);
backgroundCellImage.frame=CGRectMake(0.0, 0.0, 320.0,129.5);
customCellView.frame=CGRectMake(0.0, 0.0, 320.0, 129.5); // UIView
}

Please note ::
[UIImage imageNamed:#""] caches the image. Instead use: [UIImage imageWithContentsOfFile:#""]
To make the image equal to the UIImageView size, you should use:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
Refer: https://stackoverflow.com/a/9945160/667586

Your numbers for the frames don't add up very well. For instance, in zoomInProperties, you set fruitImage to have origin.y at 73.0, but its height is 82.5 (fractional pixels?) so it will end at 155.5, which is below the bottom of the customCellView which is 135.6. If the outer cell UIView is not set to clip, then the image will draw partly into the next cell.
Also, by setting the inner frames before setting the outer customCellView, you could have 2 changes to the sizes if they have autoResizeMask applied.

Related

UIImageView autoresizingMask behavior

I have a view tableview which display custom cells. Those cells have a UIImageView which need to be scaled if the device is in landscape mode.
I set the autoresizingMask of the tableView to UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth, did the same for my custom cells and the UIImageView.
My problem is that setting autoresizingMask for the UIImageView changes the frame of the view without any rotation of the device needed.
This is my initialisation code for my UIImageView.
- (UIImageView *)bigImageView
{
if (!_bigImageView)
{
_bigImageView = [[UIImageView alloc] initWithFrame:(CGRect){2, [self.header getHeight], 272, 272}];
[_bigImageView setImage:[UIImage imageNamed:#"square.png"]];
[_bigImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[_bigImageView setBackgroundColor:[UIColor redColor]];
}
return _bigImageView;
}
The width should be 272 but changes automatically to 232.
The result expected with autoresizingMask should be:
But I get:
The ratio is not respected anymore.
This happens because every cell starts with a height of 44 points. You can check that in the init.
Maybe you can correct the size of the cell elements in drawRect: or in layoutSubviews.

Is it possible to change the height of the placeholder rows in UITableView without creating dummy row?

The row height beyond the last row in TableView (the empty placeholder rows that are just there for visual detail if the number of items is less than the number of rows a TableView can display at once) is always the same as the last row height.
Is it possible to change this without resorting to adding a dummy last row?
The private UITableView instance method _spacingForExtraSeparators returns the height of the placeholder rows. If you're not writing an app for the App Store, just override that. It returns a CGFloat.
Here's an different approach that is App Store-compliant (as far as I know), and might be easier than creating a dummy row.
UITableView sends itself the layoutSubviews message a lot. It does this whenever it adds, removes, or rearranges cells, and whenever it scrolls (and probably other times too). So let's override layoutSubviews to draw a view that starts at the bottom edge of your table view's last section. The view will be filled with a repeating pattern that looks like placeholder cells, with a height you define.
Create a subclass of UITableView. Give your subclass a UIView *_bottomView instance variable. We need to override layoutSubviews, so we'll initialize _bottomView lazily in that method.
#implementation MyTableView
{
UIView *_bottomView;
}
Override layoutSubviews. The first thing you do in your layoutSubviews is call [super layoutSubviews] so you'll continue to act like a proper UITableView.
- (void)layoutSubviews
{
[super layoutSubviews];
The next thing you do is lazily initialize _bottomView.
if (!_bottomView) {
You need a pattern to fill _bottomView, and it needs to look like placeholder cells. Make an image context that's 1 pixel wide, and as tall as you want a placeholder cell to be. Fill the context with white, and paint a separator line (pixel, really) at the bottom. Get the image from the context.
UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, placeholderHeight), YES, 0);
[[UIColor whiteColor] setFill];
UIRectFill(CGRectMake(0, 0, 1, placeholderHeight));
[self.separatorColor setFill];
UIRectFill(CGRectMake(0, placeholderHeight - 1, 1, 1));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Next, create _bottomView, set its background "color" to that image as a repeating pattern, and add it to yourself as a subview.
_bottomView = [[UIView alloc] initWithFrame:CGRectZero];
_bottomView.opaque = YES;
_bottomView.backgroundColor = [UIColor colorWithPatternImage:image];
[self addSubview:_bottomView];
} // end of if-block
Finally, find the rect of your last section. Use that rect to compute a frame for _bottomView that starts at the bottom of the last section, is plenty tall (twice your own height is more than enough), and is as wide as the last section's rect.
int lastSectionIndex = [self.dataSource numberOfSectionsInTableView:self] - 1;
if (lastSectionIndex < 0)
lastSectionIndex = 0;
CGRect lastSectionRect = [self rectForSection:lastSectionIndex];
CGRect bottomViewFrame = CGRectMake(lastSectionRect.origin.x, CGRectGetMaxY(lastSectionRect), lastSectionRect.size.width, self.bounds.size.height * 2);
_bottomView.frame = bottomViewFrame;
Finally, make sure _bottomView is your frontmost subview so it will overdraw UITableView's placeholder cells.
[self bringSubviewToFront:_bottomView];
} // end of layoutSubviews
The end.
#end
I don't think there is a public API to do so. It is reasonable to use the last row height as the placeholder rows height.
If you insist on changing the height of placeholder rows, as I know, add an empty dummy cell at the end of your cells is the only way to do so.
Just as you've done.

Image scroller problem

hello every buddy
i want to make horizontal image scroller at bottom view and in the back of side big Image View. i don't know how to make image horizontal scroll.
Place the image view inside a scroll view whose horizontal content size is greater than its frame width, i.e.
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = CGRectMake(0, 0, 100, 100);
scrollView.contentSize = CGSizeMake(300, 100);
[scrollView addSubview:imageView];
You should use contentSize property of the UIScrollView to set its content size according to your requirement and then set the property showsHorizontalScrollIndicator to YES and showsVerticalScrollIndicator to NO . But you don't require to set these two if you set frame and content size properly. Like if _myScrollView.frame.height and _myScrollView.contentSize.height is same then you don't need to set horizontal and vertical scroll. Its vertical scroll will automatically be disabled.
you can use scroll view with page control for a horizontal slideshow. follow the tutorial it might help you
http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/

Align UITableViewCell accessoryView to bottom of cell instead of middle

In the native Mail app, the To: field has a ContactAdd UIButton on the right in the accessoryView position, but it is aligned to the bottom of the cell (which you can see as the cell grows in height). Is it possible to mimic this using the accessoryView property? As far as I can tell, accessoryViews always align in the middle.
I found that you can subclass UITableViewCell, override layoutSubviews, and in that method, get the accessoryView and adjust its frame as desired.
In my app, I found a partly-working solution with the following code:
UIImage *accessoryImage = [UIImage imageNamed:#"accessory_disclosure_bottom.png"];
UIImageView *accImageView = [[UIImageView alloc] initWithImage:accessoryImage];
[accImageView setFrame:CGRectMake(0, 10, 14, 28)];
accImageView.backgroundColor = [UIColor greenColor];
accImageView.userInteractionEnabled = YES;
cell.accessoryView = accImageView;
I got the image from http://m.tech-recipes.com/rx/UITV_accessory_disclosure.png, cut away the bottom padding and made the background transparent in my graphics program. It has the full accessor functionality when selecting the row, however the image is not colored blue when selecting, which is really annoying (it seems to ignore the background transparency altogether).

How can I modify the appearance of 'empty' cells in plain UITableView?

If you have a plain (not grouped) UITableView with a single row, the rest of the screen is filled with blank or empty cells. How do you change the appearance of these blank cells? Af first, I thought they would have the appearance of the cell used in the table view but it seems they don't.
The people from Cultured Code (Things) have done a nice job modifying these cells but I can't immediately think of a way to change their appearance.
Any tips?
Although it's not quite what you're looking for, you can also change it to just display a blank region (instead of blank cells) by setting a footer view on the table. A UIView of height 0 will do the trick.
Based on samvermette's answer, but modified to use a background image directly rather than compositing an image from a UITableViewCell subclass. Sam's answer is good, but it will be less performant than just creating a background image directly.
Create a UIView subclass -- in this example I called it CustomTiledView -- and add the following code to the class:
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed:#"tableview_empty_cell_image"];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM (context, 1, -1);
CGContextDrawTiledImage(context,
CGRectMake(0, 0, rect.size.width, image.size.height),
[image CGImage]);
}
Add the following code to your tableviewcontroller:
- (CGFloat)tableView:(UITableView *)tableView
heightForFooterInSection:(NSInteger)section {
// this can be any size, but it should be 1) multiple of the
// background image height so the last empty cell drawn
// is not cut off, 2) tall enough that footer cells
// cover the entire tableview height when the tableview
// is empty, 3) tall enough that pulling up on an empty
// tableview does not reveal the background.
return BACKGROUND_IMAGE_HEIGHT * 9; // create 9 empty cells
}
- (UIView *)tableView:(UITableView *)tableView
viewForFooterInSection:(NSInteger)section {
CustomTiledView *footerView = [[CustomTiledView alloc] init];
return [footerView autorelease];
}
Finally, you'll need to set the bottom content inset of your tableview to the negative of the value returned from -tableView:heightForFooterInsection: In this example it would be -1*BACKGROUND_IMAGE_HEIGHT*9. You can set the bottom content inset either from the Size Inspector of Interface Builder or by setting the self.tableView.contentInset property from the tableviewcontroller.
Cheers!
I set a ~300px-high UIView subclass to my tableView header and footer views, adjusting the tableView insets so they compensate for these views (set the top and bottom insets to -300px).
My UIView subclass implements the drawRect method, in which I use CGContextDrawTiledImage() to draw an empty UITableViewCell repetitively:
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 46),NO,0.0);
emptyCell = [[SWTableViewCell alloc] initWithFrame:CGRectZero];
[emptyCell drawRect:CGRectMake(0, 0, 300, 46)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
[emptyCell release];
UIGraphicsEndImageContext();
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM (context, 1, -1); // this prevents the image from getting drawn upside-down
CGContextDrawTiledImage(context, CGRectMake(0, 0, 300, 46), [newImage CGImage]);
}
In my case my tableviewcells are 46px high, so if I want make UIView subclass to contain 8 of these empty cells, I need to make it 368px high.
From http://jomnius.blogspot.com/2011/03/hide-uitableview-empty-cell-separator.html
Easy way is to define that table has no cell separator lines:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
Hard way, if you need separator lines, is to define that table has no separator lines and create cell separator lines as part of custom UITableViewCell. Bottom part of cell, obviously, and most likely using really thin graphics image. Remember to define image autosizing and mode properly.
Another way is to define an empty UITableView's tableFooterView:
UIView *footer =
[[UIView alloc] initWithFrame:CGRectZero];
self.myTable.tableFooterView = footer;
[footer release];
If you simply want to change the height of the "empty cells" when there are no cells at all in your TableView: you need to set the rowHeight property of your UITableView (the implementation of tableView:heightForRowAtIndexPath: has no effect on empty TableViews). If there are cells in your TableView and you have implemented tableView:heightForRowAtIndexPath: then the last row height will be used for empty cells.
You will probably have to make a custom subclass of UITableView that fills the background with the appearance of blank cells.
- (void)drawRect:(CGRect)rect {
[super drawRect: rect];
// draw your background here if the rect intersects with the background area
}
I believe the approach of using the UITableView tableView:viewForFooterInSection: method will not work for the case where the table is empty, ie., with no cells. In that case, you can use the technique Answerbot proposed can be repurposed to stuff the created UIView into the table's footer view explicitly, like the following:
CGRect cellRect = CGRectMake(0, 0, table.bounds.size.width, table.bounds.size.height);
CustomTiledView *footerView = [[[CustomTiledView alloc] initWithFrame:cellRect] autorelease];
table.tableFooterView = footerView;
For swift 4.0 :
self.tableView.tableFooterView = UIView(frame: CGRect.zero)