I've a UIImageView, UILabel, UIButton in my custom UITableViewCell.
When I set editing mode to YES, the entire cell frame moves too much to the right.
Scrolling the table up and down seems to fix it.
But why it happens and how can I really fix it?
In your custom UITableViewCell use layoutSubviews and willTransitionToState.
In your .h file add int state;
In your .m cell add
- (void)willTransitionToState:(UITableViewCellStateMask)aState
{
[super willTransitionToState:aState];
state = aState;
}
Also add this:
- (void)layoutSubviews
{
[super layoutSubviews];
self.contentView.frame = CGRectMake(0,
self.contentView.frame.origin.y,
self.contentView.frame.size.width,
self.contentView.frame.size.height);
if (self.editing )
{
switch (state) {
case 2:
// swipe action -> here you play with how much your content will move
self.contentView.frame = CGRectMake(90,
self.contentView.frame.origin.y,
self.contentView.frame.size.width-90,
self.contentView.frame.size.height);
break;
}
} else {
NSLog(#"subview not in edit %i",state);
self.contentView.frame = CGRectMake(0,
self.contentView.frame.origin.y,
self.contentView.frame.size.width,
self.contentView.frame.size.height);
[self setNeedsDisplay];
}
}
This should be enough to customize indent.
This usually happen due to layout of cell is not getting called use custom cell and set frames in layoutSubviews this will fix your problem
Related
I have a UIView in .xib file which I'm loading at runtime and setting it as tableHeaderView of UITableView. I have a UILabel in my xib file which can grow dynamically with fixed UIButton at bottom.
If I set the width of UILabel to fixed width it works.
If I set the Leading/Trailing on UILabel then it doesn't work :(
I'm using the below code to handle the height of headerView
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Dynamic sizing for the header view
if (table.tableHeaderView) {
UIView *headerView = table.tableHeaderView;
float height = [headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect headerFrame = headerView.frame;
// If we don't have this check, viewDidLayoutSubviews() will get
// repeatedly, causing the app to hang.
if (height != headerFrame.size.height) {
headerFrame.size.height = height;
headerView.frame = headerFrame;
table.tableHeaderView = headerView;
}
}
}
Anybody can explain why setting the leading/trailing is not working?
My view with constraint is like (without fixed width):
call in the end of viewDidLayoutSubviews.
[viewWithLabelAndButton setNeedLayout];
[viewWithLabelAndButton layoutIfNeeded];
I have code that adds a text label, a subtitle and the accessory icon like so:
cell.textLabel.text = #"Title";
cell.detailTextLabel.text = #"Subtitle";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// And I see code in the docs for an image:
cell.imageView.image = ...
But I want the place where the image goes (on the left) to be a text or lablel (like in Instagram) or a draw circle (like the Apple favorites call screen). How is this done?
Although with UITableViewCellStyleDefault you get imageView property on UITableViewCell for free and you can use it, just in case, you want to have fine control on placement of imageView and labels on cell, you need to go for custom UITableViewCell. Here are the steps on how to achieve this:
Step 1 : Create a new UITableViewCell subclass say MyCustomCell.
#interface MyCustomCell : UITableViewCell
Step 2 : Implement initWithStyle:reuseIdentifier: method in MyCustomCell.m and add any custom view to cell content view.
- (id)initWithStyle:(UITableViewCellStyle)iStyle reuseIdentifier:(NSString *)iReuseIdentifier {
if ((self = [super initWithStyle:iStyle reuseIdentifier:iReuseIdentifier])) {
MyView *myCustomView = [[MyView alloc] init];
myCustomView.frame = CGRectMake(6.0f, 6.0f, 30.0f, 30.0f);
[self.contentView addSubview:myCustomView];
}
return self;
}
Step 3 : Implement layoutSubviews method to have fine control on your cell content subviews.
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.frame = CGRectMake(6.0f, 6.0f, 30.0f, 30.0f);
GFloat textLabelXPosition = self.imageView.frame.origin.x + self.imageView.frame.size.width + 10;
self.textLabel.frame = CGRectMake(textLabelXPosition, 0.0, contentRect.size.width - textLabelXPosition, contentRect.size.height);
}
Step 4 : Finally use MyCustomCell instance in you table view controller's cellForRowAtIndexPath: method.
create an imageView image, and then add following lines to your cellForRowAtIndexPath
CGRect newFrame;
newFrame.origin.x = self.accessoryView.frame.origin.x;
newFrame.origin.y = self.accessoryView.frame.origin.y;
self.image.frame= newFrame;
this will give you the access to coordinates of accessory view. Now override with your text/ label.
create A label in your xib - yourLabel
self.yourLabel.frame= newFrame;
I am about create "No connection" view in gap between navigation bar and view controller content.
I want to subclass UINavigationViewController and move content of view controllers inside a bit down.
Question is how to do this in right way?
My current solution is working but it is also quite hacky. I would like make it better.
// subclass of AGNavigationController
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
static BOOL firstTime = YES;
if (firstTime) {
contentView = nil;
for (UIView *v in self.view.subviews) {
if ([v isKindOfClass:[NSClassFromString(#"UINavigationTransitionView") class]]) {
contentView = v;
break;
}
}
firstTime = NO;
origFrame = contentView.frame;
noConnectionView.frame = CGRectMake(0, self.navigationBar.frame.origin.y+self.navigationBar.frame.size.height, 320, 20);
}
[self adjustToConnection:NO withAnimation:NO];
}
-(void)adjustToConnection:(BOOL)isConnection withAnimation:(BOOL)animation {
if (isConnection) {
[noConnectionView removeFromSuperview];
contentView.frame = origFrame;
} else {
[self.view addSubview:noConnectionView];
contentView.frame = CGRectMake(0, origFrame.origin.y+20, 320, origFrame.size.height-20);
}
}
Create your UIView and set its frame to something like (0, 0, self.view.frame.size.witdh, 40).
Use [self.view addSubview:myView]; to add the view to your UIViewController.
Move your elements down in your main view, with the vertical offset set at myView.frame.size.height.
This is all you can get with a question like this one. If you need more help, you have to be more precise about what you tried, and what doesn't work.
I would like to create an app that has a function like iOS 7's Notes application. Basically there is one row on the top that has date and time.
My solution is to put the UITextView inside UITableView. First row is UILabel with date and time, the second row is UITextView.
I change both UITextView and UITableViewCell height according to UITextView ContentSize.
The problem is the UITextView size is large so it doesn't automatically scroll when the user hit return key.
Is there any solution to make it scroll as normal?
UITextView is a subclass of UIScrollView. I will suggest an alternative method of implementing a similar functionality. Add the label view as a subview of the text view, and set a contentInset top value of the height of the label.
UILabel* label = [UILabel new];
label.text = #"Test";
[label sizeToFit];
CGRect frame = label.frame;
frame.origin.y -= frame.size.height;
[label setFrame:frame];
[self.textView addSubview:label];
[self.textView setContentInset:UIEdgeInsetsMake(label.frame.size.height, 0, 0, 0)];
Sample project:
http://sdrv.ms/16JUlVD
Try this solution. Fix is based on inheritance. But logic can be used at any place after UITextView text was changed. I have taken some useful code blocks from here:
http://craigipedia.blogspot.ru/2013/09/last-lines-of-uitextview-may-scroll.html
and edited by me for my solution.
Should work.
#interface CustomTextView : UITextView
#end
#implementation CustomTextView
-(id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self];
}
return self;
}
-(void)textDidChange:(NSNotification *)notification {
//iOS 7 UITextView auto scroll fix.
NSRange caretRange = self.selectedRange;
if (caretRange.location == self.text.length) {
CGRect textRect = [self.layoutManager usedRectForTextContainer:self.textContainer];
CGFloat sizeAdjustment = self.font.lineHeight * [UIScreen mainScreen].scale;
if (textRect.size.height >= self.frame.size.height - sizeAdjustment) {
if ([[self.text substringFromIndex:self.text.length - 1] isEqualToString:#"\n"]) {
[UIView animateWithDuration:0.2 animations:^{
[self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y + sizeAdjustment)];
}];
}
}
}
//end of fix
}
#end
So my app has an editable and sortable UITableView in its left hamburger basement:
To make sure the table cells were skinny enough to show both the delete button and the sorting drag handle on edit, I created a custom UITableViewCell to handle the editing of the table cells:
Everything works fine on edit, but when I tap done, instead of hiding the delete button hangs around:
The code for this, inside of BookmarkTableViewCell.m, is:
- (void)setEditing:(BOOL)editing animated:(BOOL)animate
{
[super setEditing:editing animated:animate];
if (editing) {
for (UIView * view in self.subviews) {
if([[[view class] description] isEqualToString:#"UITableViewCellReorderControl"])
{
UIView *movedReorderControl = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
[movedReorderControl addSubview:view];
[self addSubview:movedReorderControl];
CGRect newFrame = movedReorderControl.frame;
newFrame.origin.x = -35;
movedReorderControl.frame = newFrame;
}
}
UIImageView *deleteBtn = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 24, 24)];
[deleteBtn setImage:[UIImage imageNamed:#"icon_delete.png"]];
[self addSubview:deleteBtn];
}
}
Let me know if you need anymore details. Any insight into fixing this would be great. Thanks!
It looks like you're adding the deleteBtn, but you aren't removing it. if editing is false you should locate the deleteBtn cell and remove it from it's superview so it goes away.