I am using EasyTableView Library, Can you please tell me , When I am dynamically creating rows for my Tableview, why it is showing so much performance lag in the Instruments?
The Code in the above image is as follows:
CGRect buttonRect = CGRectMake(10, 0, 473, 677);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = buttonRect;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, button.frame.size.height-100, button.frame.size.width,50)];
label.backgroundColor = [UIColor blackColor];
label.textColor = [UIColor whiteColor];
label.textAlignment = NSTextAlignmentCenter;
[button addSubview:label];
// Use a different color for the two different examples
return button;
It looks like you're regenerating a cell view for every cell (i.e. never reusing the views).
Looking at the docs for EasyTableView, it looks like ETV does NOT incorporate a view caching mechanism, so it's generating new views for every row of the tableview.
And if your tableview has dozens or hundreds of rows, you are in deep trouble. I suggest getting rid of EasyTableView and using UITableViews that have cell view caching and reuse.
Alternatively, implement your own view caching and reuse. So in your case you'd have a pool of UIButtons, and every time you need to return a UIButton in easyTableView:viewForRect:, check if there's one that isn't currently visible on screen. If so, reuse it and change whatever you need (label text, etc...). Otherwise, create a new one.
It's impossible to tell if you have any performance issues based on that screenshot, all there is that button takes 34% of time inside viewForRect, which is probably tiny. To get better picture open right sidebar in Instruments and see where time goes, or show your call trace with timing, not the code view.
Now, in general, creating cell views is not a bottleneck, but not reusing them in UITableView is.
Related
I'm trying to use a UIRefreshControl that has a colored background. I found that the UIRefreshControl's size is actually inaccurate when you use it on a UITableView or UICollectionView.
To highlight this, I set a background color to the UIRefreshControl and to the cells.
How do I fix this gap? This is driving me nuts. It looks very unprofessional and seems to be hidden with people using white UIRefreshControls.
Here the UIRefreshControl is flush against the UITableView
Now we start to see a little bit of a gap
Now the gap is much bigger
To reproduce this, simply have a plain Storyboard with a UITableViewController.
Relevant code:
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl setBackgroundColor:[UIColor redColor]];
self.refreshControl.tintColor = [UIColor clearColor];
Repo with code:
https://github.com/Lyricalpanda/RefreshControl/tree/master/RefreshControl
Well, in your sample app, I can make that white gap go away by saying:
self.view.backgroundColor = [UIColor redColor];
But if that's acceptable you don't need to set the refresh control's background color at all just the view's.
How do I imitate this behavior in UITableView. Wherein, if I pull the table DOWN, the header sticks at the stop, but if I scroll the table UP, the header goes with it.
Like the app store.
(scrolling up)
(scrolling down)
You can use tableHeaderView for this type of work.
In your viewDidLoad write below code.
- (void)viewDidLoad
{
**// Take one view and subview that view in the tableview.**
UIView *viewsearch=[[UIView alloc]initWithFrame:CGRectMake(0,-10, 320,83)];
[self.Yourtablename addSubview:viewsearch];
**//Now take any controls which you want to show in your header. e.x label,button,searchbar**
UILabel *lbl1 = [[UILabel alloc] init];
[lbl1 setFrame:CGRectMake(0,5,100,20)];
lbl1.backgroundColor=[UIColor clearColor];
lbl1.textColor=[UIColor whiteColor];
lbl1.userInteractionEnabled=YES;
[viewsearch addSubview:lbl1];
lbl1.text= #"BUY THE NEW APPLE TV FROM THE APPSTORE";
**//Here is the code.With the help of this code when you scroll UP the headerview hide.**
self.tbluser.tableHeaderView = viewsearch;
self.tbluser.contentOffset = CGPointMake(0, CGRectGetHeight(viewsearch.frame));
}
May be it will help you.
I use InAppSettingsKit in my projects. And everything was good befor iOS 9 update. I hadn't this problem in iOS 8. It still work but now cell alignment looks strange. Now cell content has strange offset from the left and right sides.
I've downloaded the sample project and found interesting moment. And edited one cell configuration cell. So in fact cell is green, contentView is red.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kIASKPSToggleSwitchSpecifier];
cell.accessoryView = [[IASKSwitch alloc] initWithFrame:CGRectMake(0, 0, 79, 27)];
cell.contentView.autoresizingMask |= UIViewAutoresizingFlexibleWidth;
cell.contentView.backgroundColor = [UIColor redColor];
cell.backgroundColor = [UIColor greenColor];
[((IASKSwitch*)cell.accessoryView) addTarget:self action:#selector(toggledValue:) forControlEvents:UIControlEventValueChanged];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
When controller configuring form xib it works good.
Configuration:
Result:
So... Normal left and right offsets. Have no any problems. But! after programmatically push.
- (IBAction)showSettingsPush:(id)sender {
[self.navigationController pushViewController:[[IASKAppSettingsViewController alloc] init] animated:YES];
}
I have this strange result(The same problem in my app):
InAppSettingsKit Source
P.S. Any way thanks for your attention. I would be grateful for any help.
This is actually an iOS 9 feature (cellLayoutMarginsFollowReadableWidth) that limits cells to a good readable width. And IMO your second screenshot looks better. (On a sidenote: in your first shot the section titles are incorrectly aligned - not sure what's the reason for this, works fine in the sample app here).
There's a pull request that allows you to disable this property (default is YES): https://github.com/futuretap/InAppSettingsKit/pull/317
I'll look into potential side effects and might merge this at some time.
There's are a lot of links how to size a label, however there's a lack of info how to resize UIButton according to its label size. Currently, I have screen view set with autolayout (all the system constraints are added from IB) and everything works fine, but need to add dynamic content at the bottom of the screen. I need to create and add random number of buttons with random length titles. So, here's code fragment for creating and adding the buttons:
// Loop
UIButton *myButton = [UIButton new];
UIButton.frame = CGRectMake(0, previousButtonOriginY, self.view.bounds.size.width, 20);
myButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
myButton.titleLabel.textAlignment = NSTextAlignmentLeft;
myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[myButton setTitle:#"very long title..." forState:UIControlStateNormal];
myButton.titleLabel.numberOfLines = 0;
[self.footerView addSubview:myButton];
The problem is the frame height of the button stays 20px but the label string is shown on three lines and so overlaps with the other button title. If I add [myButton sizeToFit] then button width is resized to fit all the text into one line and so the title goes beyond the screen.
If I add [myButton sizeThatFits:CGSizeMake(320, 100)] then resize is not working at all. I know sizeToFit should not be called at all because it's not the part of autolayout, however need suggestions on that how easily to make button fit its label to screen 320 width.
I feel I need to add system constraints from code, but haven't done that before, so not sure how it should look like. I probably need a ton of constraints to be added from code in order to get this simple thing working :)
Instead of using Autolayout, you could just use a collection view which better options for you to lay out elements such as buttons.
It is better able to handle layouts under rotation as well.
Or you can use this code, it worked for me...
For example, substitute your desired padding values here:
UIButton* myButton = [[UIButton alloc] init];
// setup some autolayout constraints here
myButton.titleEdgeInsets = UIEdgeInsetsMake(-desiredBottomPadding,
-desiredRightPadding,
-desiredTopPadding,
-desiredLeftPadding);
Combined with the right autolayout constraints, you end up with an auto-resizing button which contains an image and text!
For this kind of customizations you'll need to create a subclass of UIButton. In the subclass you can add a customized label which benefits your needs. You can also override to setTitle:forState method to automatically update your customized label.
I know this question is worded kind of strangely, but let me explain what I'm trying to do:
Let's say that I have an app with 2 tabs, each with their own view. Both views are almost exactly the same, except one contains a button or two that the other one doesn't, and vice versa.
I already made one view in Storyboard mode, now I want to change just a little tiny bit about it and reuse the same view for the other tab.
I don't want to do a deep copy, because if I change one, then I would have to change the other, and that might cause some inconsistency between the two.
So how should I go about using the same generic view for multiple tabs, and just change little things about it depending on which tab I am in?
Should I add the universal content in storyboard view, and then programmatically add the particular tab-exclusive content? If I did this, I would need a way to detect what tab is selected, right? Is there a way to do that?
Thank you for any suggestions!
You don't need a Storyboard for that. Sure you can drag a view in there and assign it to a specific class and program all stuff in that, but if you really need only one view in there the storyboard is useless. You should deal with subviews programmatically if you want to change something. This is very good and you have great features like animationWithDuration:
For checking which Tab in your UITabBarController is selected you can use self.tabBarController.selectedIndex and compare it with the given Index of the Tab which is selected.
EDIT:
If we assume you have a green Button on Tab with index 0, and the same Button should slide a little bit above and a red Button should appear where green Button when Tab with index 1 is tapped.
UIButton *greenButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 320, 100, 20)];
greenButton.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenButton];
UIButton *redButton = [[UIButton alloc] initWithFrame:CGRectMake(0, greenButton.frame.origin.y, 100, 20)];
greenButton.backgroundColor = [UIColor redColor];
if (self.tabBarController.selectedIndex == 1) {
[UIView animateWithDuration:1.0 animations:^{
greenButton.frame = CGRectMake(0, 300, 100, 20);
} completion:^(BOOL finished) {
[self.view addSubview:redButton];
}];
}
First you create the two buttons and add the green one to the view. (The first view is at index 0). Then you check if the selectedIndex is 1 and animate the Buttons around.