Custom CollectionViewCell - ios

I create Custom CollectionViewCell with that code and have lags then I use it. Why ?
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.webView = [[UIWebView alloc] initWithFrame:CGRectZero];
_webView.scalesPageToFit = YES;
_webView.allowsInlineMediaPlayback = YES;
_webView.mediaPlaybackRequiresUserAction = NO;
_webView.scrollView.scrollEnabled = NO;
_webView.scrollView.bounces = NO;
[self.contentView addSubview:self.webView];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
self.imageView.clipsToBounds = YES;
[self.contentView addSubview:self.imageView];
}
return self;
If I use this code all ok
- (CollectionCell *)collectionView:(IndexedCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
cell.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
cell.imageView.clipsToBounds = YES;
[cell.contentView addSubview:cell.imageView];

Since you are allocating a webview inside your initialization, I'm going to guess that's why you're seeing the lag.
UIWebView is a heavy allocation to make and since it's within a custom cell, it's probably getting called multiple times. See where I'm going?
As I stated in my comment, it's tough to really know what's going inside your application without some result from Time Profiler.

Related

Custom UITableViewCell auto layout doesn't work

I'm trying to implement a custom table cell using Auto Layout programmatically like below, but for some reason I didn't get the expected result.
Expected:
Actual:
My observation is:
The cell height doesn't grow as the content grows, and content overflows;
The bar element should be a vertical blue bar, but it's not properly showing up;
Setting background colors on the UIView elements doesn't work at all for some reason.
Please share some pointers on what I did wrong. Thanks in advance
UITableViewCell Code is below:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.infoContainer = [[UIView alloc] init];
self.title = [[UILabel alloc] init];
self.time = [[UILabel alloc] init];
self.bar = [[UIView alloc] init];
[self.infoContainer addSubview:self.bar];
[self.infoContainer addSubview:self.title];
[self.infoContainer addSubview:self.time];
[self.contentView addSubview:self.infoContainer];
self.infoContainer.translatesAutoresizingMaskIntoConstraints = NO;
self.title.translatesAutoresizingMaskIntoConstraints = NO;
self.time.translatesAutoresizingMaskIntoConstraints = NO;
self.bar.translatesAutoresizingMaskIntoConstraints = NO;
[self.infoContainer.leftAnchor constraintEqualToAnchor:self.contentView.leftAnchor constant:18].active = YES;
[self.infoContainer.rightAnchor constraintEqualToAnchor:self.contentView.rightAnchor constant:-18].active = YES;
[self.infoContainer.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:10].active = YES;
self.infoContainer.backgroundColor = [UIColor yellowColor];
[self.bar.leftAnchor constraintEqualToAnchor:self.infoContainer.leftAnchor constant:0].active = YES;
[self.bar.topAnchor constraintEqualToAnchor:self.infoContainer.topAnchor constant:0].active = YES;
[self.bar.bottomAnchor constraintEqualToAnchor:self.infoContainer.bottomAnchor constant:0].active = YES;
[self.bar.heightAnchor constraintEqualToAnchor:self.infoContainer.heightAnchor].active = YES;
[self.bar.widthAnchor constraintEqualToConstant:10];
self.bar.backgroundColor = [UIColor blueColor];
[self.title.leftAnchor constraintEqualToAnchor:self.bar.rightAnchor constant:15].active = YES;
[self.title.rightAnchor constraintEqualToAnchor:self.infoContainer.rightAnchor constant:0].active = YES;
[self.title.topAnchor constraintEqualToAnchor:self.infoContainer.topAnchor constant:0].active = YES;
[self.time.leftAnchor constraintEqualToAnchor:self.title.leftAnchor constant:0].active = YES;
[self.time.rightAnchor constraintEqualToAnchor:self.title.rightAnchor constant:0].active = YES;
[self.time.topAnchor constraintEqualToAnchor:self.title.bottomAnchor constant:10].active = YES;
}
return self;
}
and in the table view, I have:
self.recentView.rowHeight = UITableViewAutomaticDimension;
self.recentView.estimatedRowHeight = 64.0f;
Thanks!
Automatic height completely depends on hooking constraints properly from top to bottom , so you miss 2 constraints
1-
[self.infoContainer.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:10].active = YES;
2-
[self.time.bottomAnchor constraintEqualToAnchor:self.infoContainer.bottomAnchor constant:10].active = YES;
Tip : If you set top & bottom constraints here
[self.bar.topAnchor constraintEqualToAnchor:self.infoContainer.topAnchor constant:0].active = YES;
[self.bar.bottomAnchor constraintEqualToAnchor:self.infoContainer.bottomAnchor constant:0].active = YES;
Then no need for
[self.bar.heightAnchor constraintEqualToAnchor:self.infoContainer.heightAnchor].active = YES;

iOS: UITableView won't load cells when left anchor is view.safeAreaLayoutGuide.leftAnchor, but will load if it is just view.leftAnchor

I have a view controller animating in from the left edge of screen, and this view controller has a UITableView subview.
On every device and orientation except for one (iPhone X in landscape), this table view shows properly.
On the iPhone X in landscape, the table view is in the correct place but its cells do not populate until you scroll the tableView. Once you scroll, the table view is as if it had been there the whole time but with invisible cells.
This constraint causes the cells to not load:
[tableView.leftAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leftAnchor].active = YES;
And when replacing this constraint with the following, the problem is solved as well:
[tableView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
I've made the background of the UITableView red to show that it is correctly placed, but no rows are showing even though they load in the portrait orientation.
I've also tried leaving it as:
[tableView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
but doing:
[tableView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
which solves the problem for header cells:
but not content cells:
This code causes the same issue:
[tableView setInsetsContentViewsToSafeArea:YES];
I am setting up my regular cells like this :
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if([reuseIdentifier isEqual: #"LayerCell"]) {
_titleLabel = [[UILabel alloc] init];
_imgView = [[UIImageView alloc] init];
_toggleView = [[UIImageView alloc] init];
[_imgView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:_imgView];
[_imgView.heightAnchor constraintEqualToAnchor:self.heightAnchor multiplier:0.8].active = YES;
[_imgView.widthAnchor constraintEqualToAnchor:self.heightAnchor multiplier:0.8].active = YES;
[_imgView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = YES;
[_imgView.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:8].active = YES;
[_imgView setContentMode:UIViewContentModeScaleAspectFit];
[self addSubview:_toggleView];
[_toggleView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_toggleView.heightAnchor constraintEqualToAnchor:_imgView.heightAnchor].active = YES;
[_toggleView.widthAnchor constraintEqualToAnchor:_imgView.widthAnchor].active = YES;
[_toggleView.centerYAnchor constraintEqualToAnchor:_imgView.centerYAnchor].active = YES;
[_toggleView.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:-10].active = YES;
[_toggleView setContentMode:UIViewContentModeScaleAspectFit];
[self addSubview:_titleLabel];
[_titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[_titleLabel.heightAnchor constraintEqualToConstant:20].active = YES;
[_titleLabel.centerYAnchor constraintEqualToAnchor:_imgView.centerYAnchor].active = YES;
[_titleLabel.rightAnchor constraintEqualToAnchor:_toggleView.leftAnchor constant:-10].active = YES;
[_titleLabel.leftAnchor constraintEqualToAnchor:_imgView.rightAnchor constant:10].active = YES;
[self layoutIfNeeded];
}
return self;
}

Adding UICollectionViewLayout programmatically issue

I'm trying to implements this library without using storyBoard (first step for implementing this library) , because I'm creating my UIcollectionView programmatically.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.collectionView];
[_collectionView registerNib:[UINib nibWithNibName:#"myCell" bundle:nil] forCellWithReuseIdentifier:#"cell3"];
[_collectionView setBackgroundColor:[UIColor colorWithRed:0.945 green:0.945 blue:0.945 alpha:1] ];
[_collectionView setTransform:CGAffineTransformMakeScale(-1, 1)];
RFQuiltLayout* layout = (id)[_collectionView collectionViewLayout];
layout.direction = UICollectionViewScrollDirectionVertical;
layout.blockPixels = CGSizeMake(100, 100);
}
- (UICollectionView *)collectionView {
if (!_collectionView) {
CGRect collectionViewFrame = self.view.bounds;
collectionViewFrame.size.height -= (self.navigationController.viewControllers.count > 1 ? 0 : (CGRectGetHeight(self.tabBarController.tabBar.bounds))) + 0;
// FMMosaicLayout *mosaicLayout = [[FMMosaicLayout alloc] init];
//// _collectionView = [[UICollectionView alloc] initWithFrame:collectionViewFrame collectionViewLayout:mosaicLayout];
// RFQuiltLayout* layout = (id)[_collectionView collectionViewLayout];
// layout.direction = UICollectionViewScrollDirectionVertical;
// layout.blockPixels = CGSizeMake(100, 100);
_collectionView = [[UICollectionView alloc] initWithFrame:collectionViewFrame collectionViewLayout:[[RFQuiltLayout alloc] init]];
_collectionView.delegate = self;
_collectionView.dataSource = self;
}
return _collectionView;
}
But this didn't worked and nothing is shown in my view (no error and empty view that's all) Also using debugger I've notified that the UICollectionView Method are never called
First of all, your collectionView method is not called because you are using _collectionView instead self.collectionView in your viewDidLoad method. You need to write self for every property to call their setter and getter methods.
Second, if you want to add custom layout without Storyboard of XIB, then you need to set it programmatically:
RFQuiltLayout* layout = [[RFQuiltLayout alloc] init];
layout.direction = UICollectionViewScrollDirectionVertical;
layout.blockPixels = CGSizeMake(100, 100);
self.collectionView.collectionViewLayout = layout;

iOS 7 UITableView inside a popover

I have a UITableView which has some custom styling. This table view appears in two places in the app, one of which is inside a UIPopoverController. However when the tableview is inside the popover it takes on the default tableview styling as stated in the UI Transition Guide under "Popover".
The problem I have is that there appears to be nowhere to change this behaviour. Regardless of where I try and modify properties of the tableview the view inside the popover doesn't change.
Anyone dealt with this issue before or have any ideas?
Here is the init method of LibraryProductView where I create the table view:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.sectionOrdering = [NSArray arrayWithObjects:
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DESCRIPTION],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DOCUMENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_ACTIVE_INGREDIENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_PRODUCTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_DOCUMENTS], nil];
self.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:CGRectInset(self.bounds, 10, 0) style:UITableViewStyleGrouped];
self.tableView.backgroundColor = [UIColor whiteColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.showsVerticalScrollIndicator = NO;
[self addSubview:self.tableView];
}
return self;
}
Here is where the containing view (LibraryProductView) is added to the popover:
- (IBAction)didTouchInformationButton:(id)sender
{
if (_infoPopover != nil && _infoPopover.isPopoverVisible)
{
[_infoPopover dismissPopoverAnimated:YES];
return;
}
CGSize preferredSize = CGSizeMake(600.0f, 500.0f);
LibraryProductViewController* productController = [[[LibraryProductViewController alloc] initWithPreferredSize:preferredSize] autorelease];
productController.filterByMyCompany = NO;
productController.product = _activityInput.product;
UINavigationController* nav = [[[UINavigationController alloc] initWithRootViewController:productController] autorelease];
nav.title = _activityInput.product.name;
RELEASE(_infoPopover);
_infoPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
_infoPopover.popoverContentSize = CGSizeMake(preferredSize.width, preferredSize.height + 46);
[_infoPopover presentPopoverFromRect:_infoButton.frame inView:_infoButton permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
The LibraryProductView is created within viewDidLoad method of LibraryProductViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.libraryProductView = [[LibraryProductView alloc] initWithFrame:(usingPreferredSize ? CGRectMake(0.0, 0.0, preferredSize.width, preferredSize.height) : self.view.bounds)];
self.libraryProductView.dataSource = self;
self.libraryProductView.delegate = self;
[self.view addSubview:self.libraryProductView];
}
To set properties for the TableView you might do so in
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
[tableView setBackgroundColor:[UIColor redcolor]];
[tableView setSeparatorColor: [UIColor blueColor]];
return 1;
}
This, of course, assumes you have set UITableViewDataSource in your .h file

MasterViewController's TableViewController null in constructor?

I have the following MasterViewController:
- (id) init{
self = [super init];
if(self){
//self.title = #"Main Menu";
//self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"view-1_0000s_0000_Muskoka-Logo1"]];
self.navigationItem.titleView = imageView;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.opaque = NO;
self.tableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"view-1_0002s_0003s_0001_Bottom-panel"]];
self.tableView.scrollEnabled = NO;
}
return self;
}
It crashes when I try to set the background colour of the tableviewcontroller because the tableview inside the master is null. The image there is not null of course.
My only guess is that [super init] is not working properly?
A view controller's views and subviews do not exist until they have been loaded, which will occur during loadView (where the view hierarchy is built either in code or from a xib) All of those customisations should be in viewDidLoad. I'm surprised it's crashing, though, messages to nil don't cause crashes.

Resources