I am developing app where users can create Posts with attachments. For attachments I have used UITableView and rotated it in horizontal mode in viewDidLoad method as following:
// Rotates the view.
CGAffineTransform transform = CGAffineTransformMakeRotation(-1.5707963);
imageAttachmentTableView.transform = transform;
When the user chooses images from Photo Library, they are loaded in UITableView's imageView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.imageView.transform = transform;
cell.imageView.frame = CGRectMake(0, 0, 110, 110);
cell.imageVenter image description hereiew.image = [imageAttachments objectAtIndex:indexPath.row];
return cell;
}
cell.imageView is again rotated in opposite direction so that image should be visible in actual orientation
UITableView is made in editing mode so that when the images are loaded, they can also be removed by single tap.
- (void)viewWillAppear:(BOOL)animated {
[imageAttachmentTableView setEditing: YES animated: YES];
}
I have also changed the default "Delete" text to "X"
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return #"X";
}
The code is working perfectly in Portrait mode as in following screen, when the user taps '-' button 'X' appears.
http://img5.imageshack.us/img5/1125/screenshot20121221at742.png
Problem is in Landscape mode, the (-) button appears but 'X' button does not appear.
http://img833.imageshack.us/img833/6305/screenshot20121221at747.png
I have tried all possible solutions, but could not make any stick, please help
Solved it!
Problem was that in landscape mode, the UITableViewCell size and Delete button frame was changed, so i subclass UITableViewCell with my custom class.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
OMAttachmentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[OMAttachmentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.imageView.transform = transform;
cell.imageView.frame = CGRectMake(0, 0, 110, 110);
cell.imageView.image = [imageAttachments objectAtIndex:indexPath.row];
return cell;
}
In my OMAttachmentCell class, i implemented the following method.
-(void) willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect f = deleteButtonView.frame;
f.origin.x = 0;
f.origin.y = 0;
f.size.width = 30;
f.size.height = 34;
CGRect sf = self.frame;
sf.size.width = 110;
sf.size.height = 110;
deleteButtonView.frame = f;
self.frame = sf;
}
}
}
}
Here i just updated the Delete Button frame and TableCell size.
Related
In my app I display a list of items for sale in a UITableView. If the user didn't set a description on an item, I would like to adjust the positioning of some of the elements in the cell to adjust for the blank label.
The following code in my cellForRowAtIndexPath isn't working.
cell.productName.text = product.fields[#"title"];
cell.productPrice.text = product.fields[#"price"];
cell.productDescription.text = vehicle.fields[#"salespersonComments"];
if ([cell.productDescription.text isEqualToString:#""]) {
CGRect f = cell.favoriteButton.frame;
f.origin.y = 10; // new y
cell.favoriteButton.frame = f;
} else {
}
//You have to use the UITableView delegate methods
//Method for displaying the cell
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
}
//Method for adjusting the cell height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}
Rather than physically changing the coordinated/frame of the item, it would be better to have IBOutlets connected to the relevant NSLayoutConstraints.
Then you could do something like:
if ([cell.productDescription.text isEqualToString:#""]) {
cell.favoriteButtonWidthConstraint.constant = 0;
cell.leadingIndentConstraint.constant = 0;
} else {
}
I am having some odd behaviour with my UITableView. When I scroll up and down sometimes the bottom row will vanish and disappear again. Not sure why this is happening. Each of my UITableCells contains 4 buttons like so :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
int x,y;
x=5;
y=0;
for(int i = (int)indexPath.row*4; i<(int)indexPath.row*4+4; i++) {
//make sure we don't hit a blank in the array
if(i<[self.buttons count]) {
UIButton *button = [[UIButton alloc] init];
button = self.buttons[i];
button.layer.cornerRadius = button.frame.size.width / 2;
button.clipsToBounds = YES;
[button setFrame:CGRectMake(x, y, 70, 70)];
[cell.contentView addSubview:button];
x+=80;
}
}
return cell;
}
Could this be because I have the same cell reuse identifier for each cell? Does it need to be unique?
In this code:
UIButton *button = [[UIButton alloc] init];
button = self.buttons[i];
You allocate and initialize a button and then reassign the variable to entry i of a buttons array. Was this meant to be something else?
Also you are adding buttons to the cell content as a subview. Cells are reused when you scroll, so you could easily be adding more than 4 buttons to a given cell which will be causing you display issues. When you dequeue a cell it could already have 4 buttons in it.
Can you not just have 4 buttons in the cell prototype, saving you all this effort in the code.
No, cell reuse identifier need to be constant for a tableView. However you should use is as a static variable.
Change to static NSString *cellID = [NSString stringWithFormat:#"cellID",indexPath.row]; instead of
NSString *cellID = [NSString stringWithFormat:#"cell%d",indexPath.row];
Also are you making any changes in willDisplayCell or didEndDisplayingCell delegate methods. If yes Plz post that code too.
Re-write like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell.contentView.subviews.count == 0) {
int x,y;
x=5;
y=0;
for (int i = 0; i < 4; i++) {
UIButton *button = [[UIButton alloc] init];
button = self.buttons[i];
button.layer.cornerRadius = button.frame.size.width / 2;
button.clipsToBounds = YES;
[button setFrame:CGRectMake(x, y, 70, 70)];
[cell.contentView addSubview:button];
x+=80;
}
}
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
return cell;
}
}
I have a cell. Whenever the text in cell row is equal to "(null)" I want the label to be on the right hand side of the the cell.
Here is my code at the moment, but it isn't doing anything. No errors, it just doesn't align to the right hand side of the cell. Any ideas?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"ChatListItem";
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if([[itemAtIndex objectForKey:#"user"] isEqualToString:#"(null)"]){
cell.textLabel.textAlignment=UITextAlignmentRight;
cell.detailTextLabel.textAlignment=UITextAlignmentRight;
}
cell.textLabel.text = [itemAtIndex objectForKey:#"text"];
cell.detailTextLabel.text = [itemAtIndex objectForKey:#"user"];
return cell;
}
First, did you step through the code and check the contents of the value for keys "user" and "text"?
If all is as expected, you should do the following:
Replace UITextAlignmentRight with NSTextAlignmentRight to silence compiler warnings.
Explicitly set NSTextAlignmentRight and NSTextAlignmentLeft, otherwise you will not get the correct update in recycled cells.
Finally, make sure the label's width is fixed. Otherwise, the width of the label will be based on its content, so that the alignment (within the label) loses its effect.
The only working solution for your case (without subclassing of the UITableViewCell of course)
is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ChatListItem";
NSDictionary *dict = [_tableData objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = dict[#"text"];
cell.detailTextLabel.text = dict[#"user"];
if ([dict[#"user"] isEqualToString:#"(null)"]) {
[self performSelector:#selector(alignText:) withObject:cell afterDelay:0.0];
}
return cell;
}
- (void)alignText:(UITableViewCell*)cell
{
CGRect frame = cell.textLabel.frame;
frame.origin.x = cell.frame.size.width - (frame.size.width + 10.0);
cell.textLabel.frame = frame;
frame = cell.detailTextLabel.frame;
frame.origin.x = cell.frame.size.width - (frame.size.width + 10.0);
cell.detailTextLabel.frame = frame;
[cell setNeedsDisplay];
}
As for me, I would better make a subclass.
How to draw image on the right side of the UITableView cell on iOS 7 on iPad?
Tried and don't help the following code:
tableView.contentInset = UIEdgeInsetsZero;
[cell contentView].frame = CGRectMake(0, [cell contentView].frame.origin.y, cell.frame.size.width, [cell contentView].frame.size.height);
You most likely want to set the accessoryView property on UITableViewCell. This will put a an image view on the right side of a cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Configure cell
}
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"<some image name>.png"]];
cell.accessoryView = image;
}
I have an image size : CGRectMake(100,70,50,50) inside cellForRowAtIndexPath. I need to change the frame size image when the cells is odd
Code is:
if(indexPath.row %2)
{
CGRectMake(200,70,50,50)
}
else
{
CGRectMake(100,70,50,50)
}
In the first time when I load TableView, it's work ok, but when I scroll again and again, the frame size image display is in the wrong position. It changes very funny, I don't know why.
Can you help me
Thanks a lot.
You have set set the frame on your UIImageView subview:
if(indexPath.row %2) {
cell.yourImageView.frame = CGRectMake(200,70,50,50)
} else {
cell.yourImageView.frame = CGRectMake(100,70,50,50)
}
You can do it following way.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UIImageView * imageView;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
if(indexpath.row%2 == 0)
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(200, 70, 50, 50)];
else
{
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 70, 50, 50)];
[cell.contentView addSubview:imageView];
imageView.tag=11;
[imageView release];
}
}
else
{
imageView = (UIImageView*)[cell.contentView viewWithTag:11];
}
// here are couple of other statements
...............
}
Personally, I would create a custom table cell and do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ImageCell";
ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[cell configureWithRow:indexPath.row];
}
Then in your custom table cell, create an IBOutlet for your resizable image view and add a method:
-(void)configureWithRow:(NSInteger)row
{
if(indexPath.row %2)
{
self.resizableImageView.frame = CGRectMake(200,70,50,50)
}
else
{
cell.resizableImageView.frame = CGRectMake(100,70,50,50)
}
}
This does a couple of things
You don't have to check for a nil cell because you are guaranteed to get a cell back dequeueReusableCellWithIdentifier as long as the identifier matches one in your storyboard and your view controller is a UITableViewController.
You move the logic for the configuration of the cell to the custom table view cell, which is where it really should be. The view controller shouldn't care about the size of the image in the cell.