imageView in UITableView cell violates setClipsToBounds on touchdown event - uitableview

I have a UITableView whose cells have an image from a URL placed in its imageView.
The image isn't square (is landscape), however it initially loads as a square in the manner in which contentMode is scaleAspectFill and setClipsToBounds is YES. So far so good.
However, when I touch down on the cell, the image "widens", that is, it retains the scaleAspect part, but now bleeds out to the right as if setClipsToBounds is NO.
The same behavior occurs if the row/cell goes out of view and comes back in recycled, in which case I have the image obtained from an in-memory cache rather than from the URL.
I've tried explicitly setting both contentMode and setClipsToBounds for the cell.imageView, but it seems to have no effect. Any advise? Thanks.
Before touchdown:
After touchdown (or recycle from cache):

imageView cell property (same as other textLabel and detailTextLabel) changes its frame in layoutSubviews accordingly to image size. So you can reimplement layoutSubviews to have fixed frame rect. BTW, try TableKit library.

Heres a link to the correct answer if anyone is still looking for a solution: UIImageView in UITableViewCell changes size on touchDown
Its because you named it imageView, name it something like image_View and the problem is solved!

Related

UIImageView not seen by Accessibility Inspector after setting hidden to false when contained in a UITableViewCell

In our application we display a list of items and each item has an image which can either be hidden or displayed.
The issue is that if the image is initially hidden, when we set hidden = false, the image is displayed but the Accessibility Inspector doesn't identify it.
If we call reloadRows then the image is identified by Accessibility Inspector.
However, I want to avoid calling reloadRows when the visibility of the image changes because it adds complexity (weird dependencies).
What I've tried so far is the following:
call setNeedsDisplay() on the cell
post UIAccessibilityLayoutChangedNotification
Neither work.
Any other ideas of "refreshing / reloading" the cell so the Accessibility Inspector identifies the image?
Please note that I did set an accessibility identifier and isAccessibilityElement is set to true, since after calling reloadRows the image is identified.
Thanks,
Cosmin
The issue here is due to stack view. If you keep the image view outside the stack view, it should work fine. But since, you are placing it inside the stack view, and by default it's hidden, when the cell loads, accessibility order is determined in such a way that no such element(imageview) exists as it was hidden and stack view shifted other views in image view's place. To make the accessibility inspector read the image view, you need to reload the cell with image view as visible and this time it would work fine.
Alternative to reloading, you can define accessibilityElements for the cell and add image view, if visible, on the basis of isHidden property.
This would make the image view accessibile.
I have ended up making the UIImageView always visible and assign null to the image when I want to hide it, leveraging its intrinsic content size for any layout changes (forgot to mention that the UIImageView was contained by a StackView so by hiding it the StackView ended up shifting the other views - a behaviour that I wanted to keep)

The width of images in UITableViewCell changes to the click

#nathan this is my entire controller.
My problem is that when I click a tableview cell, the image size is changed and becomes too long.
I can not figure out how to fix the size, I tried everything.
To do URL parsing, I used NSXMLParser, while I used SDWebImage to load images into cells.
When I press an element its size changes.
Like this:
How to fix?
That seems like a content mode issue. Set the imageView's contentMode to aspectFit/aspectFill (depends on what you want to achieve)

Resize UIImageView with autolayout

I've got a view with a UIButton in it. I've got some animations that, among others, scale the button down.
The problem is that the button is actually scaling well following the constraints when it only has text, but when I set an image either as its image or its backgroundImage, the button is not scaling anymore.
I've tried playing with contentModes of both the UIButton and its inner imageView with no results (I've tried, literally, all the possible answers of this, this, this and this stackoverflow questions).
Any hint? Thank you all in advance
UPDATE
I've noticed that the issue is with UIImageViews, not UIButtons (the problem with the button was due to the imageView inside it).
I think your UIButton does resize, but the ImageView inside does not. The ImageView of the UIButton is always displaying normal image size.
The only possibility I found is to put another UIImageView below the Button with constraints top/bottom/left/right to the Button. This one can be perfectly adjusted.
I use subclassed buttons for that with their own ImageView inside. There you need to be careful to put userInteractionEnabled = false on the ImageView.
Finally I've got it.
In both cases (UIButton and UIImageView), you have to adjust Content Compression Resistance Priority to let the view to scale down. In my case, setting it to 749 was enough.

Custom UIView drawRect is called even with UIViewContentModeScaleAspectFill

I'm having the following issue.
Suppose I have my own image view class (to make it easy I've trimmed all the code and just included only the code that is causing the issue). That class inherits from UIView and overrides drawRect. Here is how my drawRect looks (the code is in Xamarin, but it's easy to understand)
public override void Draw(RectangleF rect)
{
base.Draw(rect);
CGContext context = UIGraphics.GetCurrentContext();
if (Image != null)
{
var imageRect = getAspectFillRect(rect, Image.Size);
context.DrawImage(imageRect, Image.CGImage);
}
else
{
this.BackgroundColor.SetFill();
context.FillRect(this.Bounds);
}
}
This code simply draws the image set to Image property in a way which simulates UIImageView's aspect fill option by calculating the rect which will display the image in aspect fill mode using this line of code getAspectFillRect(rect, Image.Size);
I also have UICollectionView with custom layout and custom cells. Each UICollectionViewCell UI is defined in an xib file, there I have all the necessary constraints set and I there I also have my custom view for displaying images. For that view in interface builder I've set content mode to "Aspect Fill". The custom UICollectionViewLayout is made in a way that cell expands (you'll see the example shortly). So the image inside the cell should also scale, and as I've set "Aspect Fill" option, it shouldn't call drawRect of my custom view, rather it should just scale already drawn content. But that is not the case!
LOOK HERE to see the video which demonstrates what happens.
You may see that the image inside is not growing together with the cell. The problem is that before ever the cell expanding animation begins drawRect of my custom UIView is called with the rect which will eventually be established after the animation. So I get a jerky animation. In my custom layout code I just call LayoutIfNeeded after updating the constraints of the cell. I don't call setNeedsDisplay, so I don't get why my drawRect is called.
For experiment I replaced my custom image view with UIImageView, I set it's content mode to "Aspect Fill", and LOOK HERE what happened. YEAH! It worked. So I suppose the issue is not in the custom UICollectionView layout, rather in my custom image drawing class.
What I should take into account?? How I should handle this case? Any Ideas?
Thanks!
DrawRect will be called whenever the system "feels" it should call it. Regardless if you call SetNeedsDisplay or not.
Now, setting ContentMode to ScaleAspectFill does not mean that DrawRect will not be called. In fact, from Apple docs here:
Instead of redrawing the contents of the view every time, you can use
this property to specify that you want to scale the contents (either
with or without distortion) or pin them to a particular spot on the
view.
This means that, if you don't want to go through the hassle of drawing the contents yourself, just set the ContentMode property. In your example, you are using DrawRect to draw.
Now, the fact that DrawRect is called before the animation starts, but with the target value for Bounds (or Frame?) means that the target value of these properties is set before the change finishes. During an animation, these properties do not change. Note during. A Bounds' or Frame's value will not change through all the values of an ongoing transition. It only knows "start" and "end".
What would happen in your app if DrawRect was not called before the animation start, but was called after animation end? Well, the cell would resize along with its subview, but your image would remain small throughout the animation and snap to the large size after the animation finished. So it's one way or the other.
Solutions:
Use the UIImageView.
If you do need to use a custom view, use a UIImageView on that to display your image.
Draw your image on a custom CALayer and add that layer on your custom view's Layer.

Adjusting UIButton's imageView properties

I'm having trouble figuring out how much I can adjust the imageView property of a UIButton. In the docs, it says:
Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s view.
I'm hoping to perform a transition where I shrink the size of the button in an animation, and I'd like the button's image to also shrink accordingly. However, I find that I have no control over the size of that image. If I modify either the frame or the bounds of UIButton's imageView property, nothing seems to happen. The image seems to want to retain it's standard dimensions. Changing autolayout properties on the imageView or contentMode properties on the button don't seem to help either.
In fact, the only thing that seems to work at all is to use UIEdgeInsetsMake to "squish" the image from all sides, but that isn't animatable.
I'd prefer not to use the backgroundImage property either, since I'm already using that to style the button in the first place.
You could add an own UIImageView as subview to the UIButton instead of using the "embedded" imageView.
You can set the frame of "your" image view as usually relative to the surrounding UIButton. You will have full control on it's position and you will also be able to animate it.

Resources