so I followed this guide ("The Technique for Static Row Content") to create my own custom UITableViewCell-s that would contain one image.
The following code is excerpt from my tableView:cellForRowAtIndexPath: method:
UIImageView *imageView = (UIImageView *)[imageViewCell viewWithTag:1];
imageView.image = [UIImage imageNamed:imageName];
cell = imageViewCell;
NSLog(#"%#", cell);
...
return cell;
imageViewCell refers to my custom cell created in interface builder. As you can see I'm trying to change image each time.
Everything works fine, but if I use reloadSections:withRowAnimation: on the UITableView, this cell disappears.
Here's console output:
<UITableViewCell: 0x9c68fe0; frame = (0 0; 302 215); autoresize = RM+BM; layer = <CALayer: 0x4b88110>>
<UITableViewCell: 0x9c68fe0; frame = (0 120; 320 102); autoresize = W; layer = <CALayer: 0x4b88110>>
<UITableViewCell: 0x9c68fe0; frame = (-320 120; 320 102); alpha = 0; autoresize = W; layer = <CALayer: 0x4b88110>>
<UITableViewCell: 0x9c68fe0; frame = (-320 121; 320 105); alpha = 0; autoresize = W; layer = <CALayer: 0x4b88110>>
<UITableViewCell: 0x9c68fe0; frame = (-320 120; 320 111); alpha = 0; autoresize = W; layer = <CALayer: 0x4b88110>>
So as you can see it's frame and alpha is changed to weird values and stays like that.
That makes sense, because I'm not initializing it each time again, it's initialized only once after waking up from nib.
How do I reset its attributes to make it visible again? I found method called prepareForReuse, but that didn't work. I need something that would reset alpha and frame to make it appear again.
Solution with loading nib each time
To be more clear about my first approach: I created the table view cell in the nib of view controller. I set up an outlet, so I could use it in tableView:cellForRowAtIndexPath:.
Since the cell's attributes were messed up after animation I figured that recreating that cell would definitely help. The problem was my nib was loaded only once and I (still) don't know how to do something like reinitialization on a view that was initialized by nib file.
So I decided to create a new nib file and load it each time. It's not exactly what I was looking for, but it works. Here's what the code looks like, it's very simple:
[[NSBundle mainBundle] loadNibNamed:#"TestTableCell" owner:self options:nil];
UIImageView *imageView = (UIImageView *)[imageViewCell viewWithTag:1];
imageView.image = [UIImage imageNamed:imageName];
cell = imageViewCell;
imageViewCell = nil; // imageViewCell is still an outlet and setting
// it to nil makes the nib load it again the next
// time - so I'm sure I'll get a new instance.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Using reloadSections:withRowAnimation: with UITableViewRowAnimationNone actually solves the problem for me, and it still shows animation on adding/deleting cells from section.
I still believe, that this is a bug in UIKit.
The cell is disappearing because something is changing its frame such that it eventually gets drawn off screen.
If the size of the image changes, the image view itself is set to autoresize and the tableview cell's content view does as well, that might cause the cell's frames to migrate depending on the order of which the images load.
Related
Problem
I can't seem to adopt Auto Layout into my existing project.
Details
I was having the same issue before as this question presentViewController: crash on iOS <6 (AutoLayout) but none of the provided answers were a solution for me: I'm using all storyboard views with no xibs. My 'Use Auto Layout' setting is already turned off and I am using nothing but iOS 6.
My view controller was initially crashing, so I set the constraints to be added with a delay and now my app crashes during any addConstraints: call. Worst part is that it won't tell me why.
Code
I will link my code, but its pretty straight forward.
-(void)addAllConstraints
{
NSDictionary * views = NSDictionaryOfVariableBindings(_memoryImage, _peopleView, _contentHolder, _commentsTableView);
NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[_memoryImage]-50-[_peopleView]-0-[_contentHolder]-0-[_commentsTableView]" options:0 metrics:nil views:views];
NSLog(#"Views %#, Constraints %#", views, constraints);
[_peopleView addConstraints:constraints];
[_memoryImage addConstraints:constraints];
[_contentHolder addConstraints:constraints];
[_commentsTableView addConstraints:constraints];
}
App crashes on _peopleView's call to addConstraints. Both the views and the NSLayoutConstraints are successfully created.
Any ideas? Thank you, Happy Holidays.
EDIT:
Adding Crash logs to show that nothing useful is showing:
2012-12-25 10:40:13.936 -----[4955:907] Views {
"_commentsTableView" = "<UITableView: 0x1eb6be00; frame = (0 372; 320 100); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1e51ce00>; layer = <CALayer: 0x1e51cee0>; contentOffset: {0, 0}>";
"_contentHolder" = "<UIView: 0x1e5c6590; frame = (0 270; 320 112); layer = <CALayer: 0x1e5c27f0>>";
"_memoryImage" = "<UIButton: 0x1e5c4aa0; frame = (0 0; 320 280); opaque = NO; layer = <CALayer: 0x1e5c4b60>>";
"_peopleView" = "<UIView: 0x1f0ceea0; frame = (0 230; 320 50); layer = <CALayer: 0x1f0cf790>>";
Constraints (
"NSLayoutConstraint:0x1e51a880 V:[UIButton:0x1e5c4aa0]-(50)-[UIView:0x1f0ceea0]",
"NSLayoutConstraint:0x1e5ba4e0 V:[UIView:0x1f0ceea0]-(0)-[UIView:0x1e5c6590]",
"NSLayoutConstraint:0x1e51b860 V:[UIView:0x1e5c6590]-(0)-[UITableView:0x1eb6be00]"
)
}
(lldb)
Constraints are supposed to be added to the view that is the superview of the subviews. So, if these objects are in your main view, then you should have (and none of the other addConstraints: lines):
[self.view addConstraints:constraints];
Also, your dictionary, views, should be nil terminated (I don't know whether this is necessary or not. I've noticed in an Apple example that they didn't do this, but the function definition shows it with the nil).
When I create a label in Interface Builder and hook the outlet to a viewController, and log the label in viewDidLoad as follows:
NSLog(#"label: %#",self.label);
It gives me a frame of (0,0,0,0). self.view gives me a size over 0. An older program's label also gives me a size over 0. It will log the text in the label, so it is hooked up right. Is this a change in Xcode 4.5? How do I access the frames that I set in Interface Builder?
this is the log:
UILabel: 0x754e1b0; frame = (0 0; 0 0); text = 'this is a label'; clipsToBounds = YES; opaque = NO; autoresize = TM+BM; userInteractionEnabled = NO; layer =...
Usually the frame layouts are unreliable in viewDidLoad. In the case of a nib this shouldn't be a problem. Are you using AutoLayout by any chance ?
Please also log the same values in viewWillAppear, this will certainly have the correct values. I usually use viewWillLoad to initiate my UI elements, and viewWillLoad to place them correctly.
Try this:
NSLog(#"Label Frame: %#",NSStringFromCGRect(self.label.frame));
I have a Nib with a scrollview which i use on my controller. I have to make some constant calculations based on the scrollview.subviews count. However, surprisingly the scrollview is always starting with two uiimage views.
The scrollview at my Nib file is empty, and i have even checked the nib source code to assure there is no garbage there. I also deleted the scrollview and created another with the same result.
I am always receiving the same views there (always at, so my scrollview.subviews.count always start at 2. What could be causing this??
If I print scrollview subviews just after initializing view..
[[NSBundle mainBundle] loadNibNamed:#"TileScreen" owner:self options:nil];
NSLog(#"Started scrollview with subviews %#", _scrollView.subviews);
I receive:
Started scrollview with subviews (
"<UIImageView: 0x1dcb50; frame = (294 400; 7 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x1e51b0>>",
"<UIImageView: 0x1bb6a0; frame = (294 400; 7 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x1a9b50>>"
)
Well before I posted this question I understood the problem. I wanted to share in case someone falls into this.
The problem is that the "Show horizontal scrollbar, Show vertical scrollbar" add the mentioned UIImageViews. You can avoid this by simply unchecking the property on the IB.
If you want to show the scrollbars though, you will need to take into account these two views in your count.
I have a Controller of which I have a few subviews. At a certain point in the code, I remove them, and then later on, I add them. Here is the code I use to add them:
[self.view addSubview:dateLabel];
[self.view addSubview:tableView];
Right after these lines, I print out:
NSLog(#"%#",[self.view subviews]);
and the output I get is:
"<UINavigationBar: 0x614a8f0; frame = (0 0; 320 48); layer = <CALayer: 0x6129ee0>>",
"<UILabel: 0x614d500; frame = (0 48; 320 25); text = 'Dec. 15, 2010 - Jan. 15, ...'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x614d570>>",
"<UITableView: 0x507ee00; frame = (0 73; 320 390); clipsToBounds = YES; layer = <CALayer: 0x9f57930>; contentOffset: {0, 0}>"
However, the only thing I see on my screen is the navigation bar. Why is the label and the tableView not showing up even if it says here that it is a subView?
I have also tried to add the following code after adding the subviews:
[self.view bringSubviewToFront:tableView];
[self.view bringSubviewToFront:dateLabel];
but it still does not work.
Is your controller a UIViewController? Have you checked it has been presented correctly? For example with presentModalViewController:self ?
I want to put a UIImage in the left side of each row in a UITableView. This is pretty standard, and is supported directly by UIKit. But putting in a (large) image causes all kinds of wonkiness, so presumably I'm supposed to scale the thing correctly myself. But none of the docs give a default size for this image using the standard out of the box views-- I'm surprised.
Others on SO indicate that 44 is the default height of a row (What is the default height of UITableViewCell?) Is 44x44 the "default" image size?
Thanks!
40x40
UITableViewCell's imageView fit to 40x40
Need to make imageView filled in 40x40... I am using SDK 3.0 with build in "Cell Objects in Predefined Styles"...
I'm on Xcode 4.6.3 building for iOS 6.1. I tried 2 sizes of image assigned to imageView of the UITableViewCell: 48x48 and 128x128 pixels. This was run in the iOS Simulator (iPad).
In the UITableViewDelegate, I put the following line in tableView:didSelectRowAtIndexPath: and put a break point right after it.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
In lldb, I get this output:
(lldb) po cell
$0 = 0x0751a720 <UITableViewCell: 0x751a720; frame = (0 88; 180 44); text = 'widget'; autoresize = W; layer = <CALayer: 0x751a6f0>>
(lldb) po cell.imageView
$1 = 0x0751a1e0 <UIImageView: 0x751a1e0; frame = (0 0; 43 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x751a1b0>>
The only conclusion I can reach based on this evidence is that the default image size is not 40x40.