Autolayout - UITableViewCell with ImageView - Margin? - swift

I have a problem when i will try to make a left/top/bottom margin with an UIImageView in a cell. It don't care what i will try to set as Top/Bottom/Left Space, i will always get the same result -> all Images are without any margin.
I have a fixed height and width, i will just want to add top/left margin.
Is there any way to force the Autolayout to add a margin here?
Thanks in advance for any tips.
Edit:
Thanks for you answer. Ill tried it, but its still not working. There is always no margin between cell and image:
Here are my constraints. (ill just take 8px as space to superView)

Actually i could't get quite to work on this issue. but i am sure that it will going to work if you try this things in your code.
Using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights
Edit:
Set the new UIImageView size and position to the values shown in the screenshot below.
Now select UIImageView and add following contraints.
Set leading, top and bottom to 20.
Set width and height to 100.
Make sure that Constrain to margins is not checked.
Tap the Add 5 constraints button.
Select the image view to show its constraints, and then select its bottom constraint to edit it. In the attributes editor, change its Relation to Greater Than or Equal and its Priority to 999.
Next, select the image view to show its constraints and then select its height constraint. In the attributes editor, change its Priority to 999.
Likewise, select the image view’s width constraint and change its Priority to 999.
To set following constraints, you will get you answer.

Add this code in cellForRowAtIndexPath
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectZero];/// change size as you need.
CGRect frame = separatorLineView.frame;
frame.size.height = 5.0;
frame.size.width = tableView.frame.size.width;
separatorLineView.frame = frame;
separatorLineView.backgroundColor = [UIColor redColor];
[cell.contentView addSubview:separatorLineView];
return cell;
OR
Follow these links Autolayout or Autolayout programatically
Now use these constraints
storyboard
simulator
This might helps you :)

Related

Trying to update parent view frame according to UILabel's text size

I have a view and inside it I have a UILabel. I want the view to change its width according to the length of the text.
What I tried is to first perform SizeToFit() on my UILabel, hoping this will change its frame, and then put the labels frame into the view's frame.
This doesn't work, I guess because of auto layout restrictions.
This is the code of what I tried:
private func example(){
self.labelInsideView.sizeToFit()
viewThatContainsLabel.frame = labelInsideView.frame
self.layoutIfNeeded()
}
It seems pretty obvious that this won't work, because I am pretty sure size to fit does not change the frame. Is there any way to achieve this?
Make an IBOutlet of your UIView's width constraint and then simply change the width constraint constant to the width of UILabel
self.labelInsideView.sizeToFit()
self.widthConstraintOfView.constant = labelInsideView.frame.size.width
self.layoutIfNeeded()
Why are you even using this function. Your view should have constraints.
Leading = Top = Bottom = 8 and Trailing >= 20
Your label should have all the constraints equal to 5.
Now try and add any text in your Label and you'll get updated frame of the view without using this function. Just try this once.

UIScrollView autoresize contentSize?

Fair warning, I'm fairly new to iOS and may be missing something obvious.
I have a UIScrollView with a few fields and those fields height can change (UITextView that stretches to fit text, collapsable fields etc). Obviously I want the scrollview contenSize to fit the content in order to allow scrolling.
Right now I have it set to re-calculate and set the contentSize every time something changes, which works fine but is there a better way to do it? In other words, if another developer now adds a field and doesn't remember to add it to the re-calculation function, unless I'm mistaken, the scrollview contentSize will be wrong even though the field is on the scrollview? Is there no way to have it "automatically" resize with it's content change?
Yes, there is a better way to accomplish this with autolayout. Apple has a very good document for using autolayout with scrollviews here. I prefer the pure autolayout approach, however in order to apply that approach you must ensure that the size of your fields are not dependent on the size of the scrollview, which makes sense. However make sure that your constraints extend to all the sides of the scroll view, so that the scrollview can determine the size of it's content.
(ie #"H:|[textView(==view)]|" and #"V:|[textView(50)]|" where '|' denotes the scrollView of which the textView is a subview and '==view' just specifies that the width of the textView must be the same as that of the view 'view'.)
If autolayout is an option for you then go with it - as Tyler stated autolayout abstracts the resizing away for you! :)
Unfortunately i have no experience yet with autolayout, so I can't tell you more about that.
Without autolayout there is no better way as far as i know.
There's nothing like "sizeToFit" or "sizeThatFits" that would take over the task of resizing the content size automatically. You have to re-calculate the content size yourself.
For that purpose either use your custom method for this re-calculation task or check out some 3rd-party categories on UIScrollView that allready have this implemented and abstracted away for you.
For example: UIScrollView+MTUIAdditions.m
(see the implementation for UIScrollView (MTUIAdditions))
The best solution
//autoresize scrollView
CGFloat scrollViewHeight = 0.0f;
CGFloat scrollViewWidth = 0.0f;
for (UIView *view in self.scrollView.subviews) {
CGFloat height = (view.frame.size.height + view.frame.origin.y);
scrollViewHeight = ((height > scrollViewHeight) ? height : scrollViewHeight);
CGFloat width = (view.frame.size.width + view.frame.origin.x);
scrollViewWidth = ((width > scrollViewWidth) ? width : scrollViewWidth);
}
[self.scrollView setContentSize:(CGSizeMake(scrollViewWidth, scrollViewHeight))];

UILabel inside custom UITableViewCell not drawing at the correct size

I have a custom table cell which contains a number of UILabels. At runtime, I am adjusting the height of the labels to fit their contents using sizeWithFont:constrainedToSize:lineBreakMode: and repositioning them accordingly. The last label in the cell contains a large amount of text, causing it to wrap, and I'm having a very odd problem. Although the sizeWithFont call returns the correct size, and I'm setting the UILabel's frame to that height, it draws a couple of lines short. This screenshot illustrates what I'm talking about:
In this example, the height of the full block of text should be 90 (as checked in Interface Builder), and that's what returns from sizeWithFont. It's also the height that the UILabel's frame is set to, which I have verified by logging and also by stopping execution and inspecting the value. However, as you can see, it's clearly not drawing the full 90 pixels high, although it's correctly allocating the space for it (the thin black line above 'Edited' is the table cell border). I'm completely perplexed. If anyone can offer some insight as to why it's behaving this way, I would be very grateful.
At last, a solution!
Turns out that the cell does layout twice -- once during heightForRowAtIndexPath, which is where I tweak all the heights of the subviews and the cell, and later during some untraceable transaction originating in __CFRunLoopDoObservers. How did I trace this? I added a layoutSubviews override to my custom table view cell class so I could breakpoint it.
During the second pass, the last UILabel subview was getting set to a shorter height than I set it to, probably in accordance with some arcane autoresizing rules. (Yes, I tried tweaking all of those settings first, with no success.) As it turns out, merely doing nothing in layoutSubviews disabled this framework behavior, allowing me to completely control how my views draw.
With iOS 8 it doesn't work anymore like this. Implementing layoutSubviews alone doesn't do the trick, because the layout of subviews have already changed when the method is called.
I have found 2 solutions:
adding NSLayoutConstraint to layout the subviews programmatically
implementing subview's layoutSubviews and change the frame
An example für solution 2:
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect frame = self.frame;
frame.size.height = 39.f;
self.frame = frame;
}
I've fought with similar problems. It was to do with other properties being set in previous incarnations of the cell. To find it / prove it I changed the reuseidentifer for the offending cell to make sure it was a unique cell.

How to change the width of the row of a UITableView

Can we resize the width of the row of a UITableView.
What exactly are you trying to accomplish?
I'm not 100%, but I am pretty sure each row is going to be with same width as the parent table. However, if you have a custom UITableViewCell, you can make it transparent, and organize your objects on the cell's view to mimic a different sized cell. For example if you wanted a cell to be 50px less wide than the other cells and indented, you could place a white UIView on the transparent cell, make it 50px less wide than it should be, and position it to the right.
Make sense?
I understand this is an old question, but I need a table cell to be less than the width of the screen, but still be scrollable by touch on either edge, and the cell highlight not to be full width.
I overrode the UITableViewCell setFrame method, like so:
- (void) setFrame:(CGRect)frame {
if (frame.size.width > 540.0f) {
frame.origin.x = (frame.size.width-540.0f)/2.0f;
frame.size.width = 540;
}
[super setFrame:frame];
}
I guess this is a slightly hacky solution, but it works a treat!
Hope this helps someone.
Only if you fit the whole table into a smaller area.

Drop shadows on iPhone Clock App "Alarm" tab

In the clock app that comes with the iPhone there is a tab view for setting alarms. In that view each of the UITableViewCell instances have a drop shadow around them. Does anyone know how to achieve the same effect?
Also it looks like the tab bar at the very bottom has a drop shadow above it as well.
Ideas on how to achieve the same look would be greatly appreciated.
I was wondering how to do that and it just occurred to me to use the UITableView's footer view:
myTableView.tableFooterView = myCustomViewWithDropShadowImage;
I would guess that there is an extra cell which contains just a background image which is the transparent dropshadow. If it's not a cell (because that might create scrolling weirdness) it is probably an extra view positioned below the bottom cell of the UITableview which - again - simply contains an image of the drop shadow.
Like Thomas said, create a 100% width image (say, 320 x 40px on non-retina devices) and create 4 instances of UIImageView with it. The first, at the top of your main view. The second, at the bottom, and in addition do this:
UIImageView* bottomShadow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BottmShadow.png"]]
bottomShadow.transform = CGAffineTransformMakeScale(1, -1);
(Flip it vertically)
Then, do the same with the other two, but place them as subviews of the Table View. One of them just outside the first row:
CGRect tableTopShadowFrame = tableTopShadow.frame;
tableTopShadowFrame.origin.y = -(tableTopShadowFrame.size.height);
[tableTopShadow setFrame:tableTopShadowFrame];
and the other just below the last row (you need to know the height of all the rows together. If your rows are all the same height, it is row height times number of rows).
Finally, you need to set the table's backgroundColor property to transparent
tableView.backgroundColor = [UIColor clearColor];
and possibly set some darkish gray for your main view's background color.