How to scale UIImage to fit dimensions of UIScrollView? - ios

I have a UIImage of dimensions 300x600 (height x width). UIImage's relative hierarchy is like so :
Using AutoLayout, I have set the following constraints for the UIImageView, UIScrollView and UIVIew:
I have set relative height dimensions of the TableView as follows:
// Setting Last Row to height = 70 pixels and first row to fill balance of screen:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 1 { return 70 }
else { return tableView.frame.size.height - 70 }
}
What I would like is for the height of the UIImage to exactly match the height of the UISCrollView that it sits in. I am not concerned about the eventual width of the UIImage, but would like it to follow confines of 'AspectFit'. So I would probably employ
imageView.contentMode = UIViewContentMode.ScaleAspectFit
... probably in
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
I would set the dynamic height and width parameters of the UIScrollView, and then set the UIImage height to follow the height of the UISCrollView and allow the ScaleAspectFitto automatically handle the width.
I have tried various renditions of code to achieve this, but have failed to achieve the desired result.
Question: Am I on the right track? Can anyone kindly get me started with some skeleton code so I can customise it to my needs.
Side Note: I am only allowing for portrait mode of my app. No landscape.
Many thanks in advance for your kind attention and time ;)

I would make a container UIView to hold the exact UIScrollView then I can create constraints of scroll view's child UIImageView to that of the container view i.e. equal heights.
As I suppose, these constraints are to their parents like
UIView <--> UIScrollView <--> UIImageView
but try them as
UIView <--> UIImageView

Related

How Can I make any View Rounded In Ball Shape Even In Big Screens Like iPad when this view equal height , width to it's superView

The Question
how can I keep Buttons, Images, Buttons...Views rounded in big screens when using constraints of ( buttons, images....views ) equal width and height to superview using swift
The Code I've Tried
I tried this block of code and It works fine in small screens like SE..until 8 :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
roundedObject.layer.cornerRadius = roundedObject.frame.width / 2
roundedObject.clipsToBounds = true
}
the shape of the different sizes screens
my object constraints:
screen1 screen2 screen3
the issue is your constraint
you will not get a square by using proportional width and proportional height constraint together like that, because different device will have different height and width
my suggestion is to use only one proportional width or proportional height (which one you want) and use aspect ratio constraint 1:1 on the roundedObject
Probably you're doing that in viewDidLoad method where the frames didn't get the final value yet (initially they get the values from the storyboard from where they were instantiated. So if in the storyboard preview the size is f.e. 300x300, in the viewDidLoad it also will be 300x300).
So either do that in the viewDidLayoutSubviews or create a subclass and do that in the layoutSubviews.
class RoundedButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
layer.corderRadius = bounds.width / 2
layer.masksToBounds = true
}
}

Resizing UIView causes child table UITableView to disappear

I have a UIView which contains a label, a button, and a UITableView which populates its data dynamically from a server. I am having trouble resizing the parent UIView to fit its content after the content has dynamically populated. For the purpose of demonstrating my issue, I have made the background of the containing UIView blue.
After populating the TableView with data, the UIView's height does not adjust causing the Tableview data to overflow, seen in the diagram below.
I have set the bottom, leading and trailing space constraints of the TableView to the superview, and top space constraint to the button. The UIView itself has no height constraints set.
I implemented a function to manually recalculate the height of the UIView after populating the content of the TableView. Code for the function below:
func resizeToFitSubviews()
{
var w: CGFloat = self.frame.size.width,
h: CGFloat = 0
for view in subviews {
if view.frame.origin.y + view.frame.height > h { h = view.frame.origin.y + view.frame.height }
}
self.frame.size = CGSize(width: w, height: h)
}
This function works. The UIView resizes to what seems to be the right size, but the TableView disappears after doing so:
Completely lost as to why this occurs. The label and button seem unaffected. I either need to make it so autolayout automatically adjusts the height of the UIView, or make it so that resizing the UIView does not cause the TableView to disappear.
In the View Debugger, the TableView is returning a height of 0 (while the rows are returning 130 as expected given that is what I return in my heightForRowAt function).
Thanks
Don't adjust the view frame if you are using Auto Layout.
Make a height constraint and adjust that to your calculated value.
-
Also it might be easier to manually calculate this height.
height = numberOfRows * heightPerRow

How to resize UIImageView in UITableViewCell?

I want to display image in cell, and because I need to download it first so I would like to display (for question simplicity) black view with the same width and height like image should be displayed.
Because I want to stretch image to same width as cell width, I only need aspect ratio for setting height and this is provided in my code when cellForRowAt is called.
I decided to achieve "black view" before downloading image I only need one UIImageView with black background, and resizing it when cellForRowAt is called. But here is the problem, because using code from similiar questions is not working for me.
I tried something like this in cellForRowAt method:
var frame cell.imageView.frame
frame.size.height = CGFloat(aspectRatio) * frame.size.width
cell.imageView.frame = frame
EDIT
As a result I want something like facebook, where we have photo with the same width as cell and height accordingly to aspect ratio. For simplicity cell can only have UIImageView.
Since you're using auto layout, in the storyboard you should set two things:
First, set the width of the UIImageView to be the full width of the cell
Second, set the aspect ratio of the UIImageView to 1:1 - this says the height is always the same as the width.
If you're using the UITableView's Automatic Dimensions for cell heights, this should be all you need; no code anywhere, everything else is as normal.
If you're not using the automatic cell height feature, then either set the cell height once with self.tableView.rowHeight = self.tableView.bounds.size.width if they're all the same, or, if the cells can be different heights:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (<indexPath IS IMAGE ROW>)
return tableView.bounds.size.width
return <default height>
}
Where I've written <indexPath IS IMAGE ROW>, you should replace that with whatever condition you need to detect if this particular cell is an image type.
Also, as Rikh pointed out, where I've written <default height>, you should replace that with the height of the cells that are not the image type.
Of course, you may have a much more complex design for your table; this just covers the case you were asking about.
here my solution
imageView.contentMode = UIViewContentModeCenter;
if (imageView.bounds.size.width > ((UIImage*)imagesArray[i]).size.width && imageView.bounds.size.height > ((UIImage*)imagesArray[i]).size.height) {
imageView.contentMode = UIViewContentMode.ScaleAspectFit;
}

UIImageView cover entire UITableViewCell using aspect fill

In the interface builder, I'm trying to create a prototype cell with an image that covers the entire cell but it is not running how it is expected.
As you can see in the following screenshot of my interface builder, I have an image view covering the entire cell, and is constrained to each edge of the cell:
And in fact this is how I expect it to look on the simulator, but instead I get this:
Where as you can see, it is not anchored all the way to the sides, and it may be hard to see, but the image actually extends past the bottom of the cell (if you look hard enough you can see the separator striking through the bottom portion of the image.
This is really buggy and I really have no idea what's happening.
Perhaps adding aUIImageView inside of your cell in code.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//configure cell
let imageView = UIImageView(frame: self.cell.frame)
imageView.image = YOUR_IMAGE
imageView.center = cell.center
imageView.frame.size = cell.frame.size
imageView.contentMode = .ScaleAspectFill
cell.addSubview(imageView)
}
Hope this helps.
I think you accidentally disabled cell's Clip Subviews in code or in Storyboard, by default It should be enabled.
If it's not the cell, check it's Content View.
By the way, by disabling Clip Subviews for both Cell and it's Content view, I managed to reproduce your bug.
Seems that your image constraints are relative to cells contentView margins. You can disable it, see screenshot. Be sure that constant is 0
You need to do Clip Subviews (clipsToBounds) on cells contentView or imageView if you don't want aspect filled image to go beyond bounds. Otherwise you should use Aspect Fit, or Scale To Fill, or do the math manually
This is because you are setting constraint to margins.
When adding constraints to uiimageview. Uncheck constraint to margin.

UIView inside custom UITableViewCell wrong width / height

I ran into the following problem. I have a custom class UITableViewCell with a few UIViews inside, which act as container for chartviews.
The problem is if I do the following:
self.upperLeftChart = XYPieChart(frame: CGRectMake(0, 0, self.upperLeftContainer.frame.width, self.upperLeftContainer.frame.height))
self.upperLeftContainer.addSubview(self.upperLeftChart)
The Chartview is as big as the whole UITableViewCell instead of the size of my container.
If I print the size of my container
NSLog("\(self.upperLeftContainer.frame.width) / \(self.upperLeftContainer.frame.height)")
it prints: 320.0 / 568.0 which is wrong. My container is about a quarter of the whole cell.
I guess it hast something to do with my Autolayout + Constraints. If I set the size to 120x120px hardcoded, it works nicely.
Any trick to get the real width and height of UIView arranged with autolayout and constraints?
What you need to do is to override
override func layoutSubviews() {
super.layoutSubviews()
self.upperLeftCart.frame = CGRectMake(0, 0, self.upperLeftContainer.frame.width, self.upperLeftContainer.frame.height)
}
That way it will change frame of the view every time cell resizes

Resources