Dynamically changed UIImage width - ios

I have UIImage like this with place for UITextField at free white space between red lines at left side:
UIImage real borders bigger than visible part because gesture recognizer linked to this image and it needs to be bigger for more comfortable using with gestures.
Text alignment in text field set to right side. So task is to crop image frame from left side depending on entered text length, when keyboard dismissed after entering text. I used this code:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
ruleImage.layer.anchorPoint = CGPointMake(1,1);
[ruleImage setFrame:CGRectMake(0, 0, 120 + ruleTextfield.text.length * 15 , ruleImage.frame.size.height)];
}
But this code compressed image horizontally, not cropped, and from left to right. So questions:
how to set anchor point to top (or bottom)right corner?
what property can I use to crop image?
P.S. also I tried
ruleImage.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
ruleImage.contentMode = UIViewContentModeTopRight;
but this properties not solved my problem.

Try
ruleImage.contentMode = UIViewContentModeScaleAspectFill;

Related

UITableViewCell Transform Breaks in iOS 11

In an app I've built, I had a table view showing an image to the left of each cell by running the following code inside of cellForRowAtIndexPath:
cell.imageView.image = [UIImage imageNamed:myImage];
But the image was too big, so I shrunk it:
cell.imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);
This worked just fine in iOS 10. But once I upgraded to the newest Xcode with the iOS 11 SDK, the images got enormous. It turns out that that second line of code transforming the image view is now doing nothing: I can comment it out, change the 0.3's to something else, etc., and it doesn't make any difference. CGAffineTransformMakeScale still has documentation in the new Xcode, so I'm assuming it wasn't deprecated, but then why did this break with iOS 11, and how do I fix it? Any ideas? Thanks in advance! Please note, I'm using Objective-C.
Edit:
Just tried 3 changes to the code:
Change the second line to cell.imageView.transform = CGAffineTransformMakeScale(0.0000001, 0.0000001);. Nothing happens (i.e., the image views and the images inside them are still just as huge).
Change the second line to cell.imageView.transform = CGAffineTransformMakeScale(0, 0);. The image disappears from the image view, but the image view is still the same size, and you can tell because it still displaces the text in the cell and pushes it far to the right.
Remove the first line of code (no longer assigning an image to the imageview). The imageview disappears, and the text moves all the way to the left of the cell.
Perhaps this can help shed some light on what's going on?
So if you are trying to adjust the image size to fit the imageView you should actually use the imageView's contentMode property like so:
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
or in Swift for others
cell.imageView.contentMode = .scaleAspectFit
This keeps the dimensions of the image and fits the maximum size image onto the imageView without changing the dimensions
You could also try UIViewContentModeScaleAspectFit (or .scaleAspectFill in Swift) which basically fills the dimensions of the imageView entirely, but if the picture is wider or taller than the image view it crops what can't fit.
Here are all the contentModes directly from a Obj-C and Swift source files:
typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
};
public enum UIViewContentMode : Int {
case scaleToFill
case scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
case scaleAspectFill // contents scaled to fill with fixed aspect. some portion of content may be clipped.
case redraw // redraw on bounds change (calls -setNeedsDisplay)
case center // contents remain same size. positioned adjusted.
case top
case bottom
case left
case right
case topLeft
case topRight
case bottomLeft
case bottomRight
}
EDIT:
Since I see you're also interested in changing the dimensions of the imageView itself ("to leave more room for the text") what I would suggest is actually, either in storyboard or programmatically use AutoLayout to add your own imageView and have it sized and placed how you want it, instead of using the default imageView on a cell which is meant as a convenient/standardized tool.
If you are unfamiliar this I would google for an AutoLayout tutorial. Or maybe "using AutoLayout to create custom UITableViewCell"
If you dont actually want to create your own subclass you can try setting the `cell.imageView.frame = ..." somewhere to manually resize it to what you want, then setting its content mode to make sure the image fits nicely still.
See this question: How do I make UITableViewCell's ImageView a fixed size even when the image is smaller
Found an answer to my own question, with credit due to Paul's answer from this question: How to resize a cell.imageView in a TableView and apply tintColor in Swift
CGSize itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContextWithOptions(itemSize, false, 0);
CGRect imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I still don't know why the old CGAffineTransformMakeScale doesn't work anymore, but this gets the job done.

Layout in UIScrollView

I am new to UIScrollView, and they are driving me crazy.
I am trying to create a screen that has a title and some descriptive text at the top, and then a scroll view (with paging enabled) in the bottom two thirds of the screen. This scroll view will contain 1-3 images. Ideally, I'd like the first image to appear centered in the initial scroll view window, and then enable the user to view the other images by scrolling/paging horizontally, again ideally with each image centered in its 'page'.
The code below loads the images for 'item' from the Internet, creates a UIImageView for each, and inserts them into the scroll view. According to the frame calculations, I would expect the first image to be up against the left side of the scrollview, and then the other images to the right, with no space between them. But instead, the first image is shifted to the right, about half-way across the screen, and there are equally large spaces between each image.
I have turned off paging to simplify matters, and I have tried experimenting with tweaking the image frame values, trying to understand what's happening, but nothing works as I expect it to.
I am guessing that autolayout is messing with me. Can someone confirm that, and maybe give me some hints on how to get this scrollview under control?
Thanks in advance.
self.imageScrollView.contentSize = CGSizeMake(self.imageScrollView.frame.size.width * (imageFieldNames.count),
self.imageScrollView.frame.size.height);
self.imageScrollView.pagingEnabled = NO;
CGFloat xPos = 0.0;
for (NSString *field in imageFieldNames) {
NSString *name = [self.item valueForKey:field];
if (name.length > 0) {
UIImageView *iv = [[UIImageView alloc] init];
iv.contentMode = UIViewContentModeScaleAspectFit;
[self loadImage:iv withFile:name];
iv.frame = CGRectMake(xPos, 0.0,
self.imageScrollView.frame.size.width,
self.imageScrollView.frame.size.height);
[self.imageScrollView addSubview:iv];
xPos += self.imageScrollView.frame.size.width;
}
}

UIButton background image used for animation not aligned across devices

I have a UIButton backgroundImage that I use to display a weather condition image when the loading is complete. I also create a UIImageView that replaces the UIButton to animate a series of images as a progress indicator.
My question: How can fix this animated UIImageView x-axis misalignment across multiple screen sizes?
Here's what the sequence looks like on 4.7" iPhone, the red box indicates the image I'm talking about:
First, the UIImageView animating as a progress indicator (imagine it spinning, alignment is correct)
Second, the download complete, the progress indicator replaced by a UIButton with a backgroundImage:
Third, the UIImageView animating on 4" iPhone (note misalignment on x-axis):
Fourth, the download complete, UIButton replaces it, aligned correctly:
Here's how the UIImageView *progressIndicator is configured.
Note that conditionButton is the UIButton with backgroundImage of the weather condition:
self.progressIndicator = [[UIImageView alloc] initWithFrame:self.conditionButton.frame];
self.progressIndicator.contentMode = UIViewContentModeCenter;
self.progressIndicator.animationImages = #[...long series of images...];
self.progressIndicator.animationDuration = 0.5f;
[self.conditionButton setBackgroundImage:[UIImage imageNamed:#"empty.png"] forState:UIControlStateNormal];
[self.progressIndicator startAnimating];
[self.view addSubview:self.progressIndicator];
I'm pretty sure the issue is with
self.progressIndicator = [[UIImageView alloc] initWithFrame:self.conditionButton.frame];
But I'm not sure how to resolve this.
The same problem occurs when I switch to 5.5" iPhone. I have no Auto Layout warnings, and the constraints that apply to the conditionButton are:
Align Center X to superview
Width = 94
Height = 94
Bottom and Top space to nearest neighbor = default
Any help would be greatly appreciated!

Make a white label visible on top of bright image view

Basic issue:
I believe the trick is with masking, but I am not able to get a good hold of how this is set.
Basically I have a bright image (set to a uiimageview object), and I have a label at very bottom (which is added on top of the image view) needs a well readable white text on it. Right now, the white text is hard to read (because of the bright background).
What I am doing:
I am setting a mask for the image view with something like
http://cl.ly/image/0i0N1p271d42
maskContainer = [CALayer layer];
UIImage *maskImg = [UIImage imageNamed:#"mask_profile"];
[maskContainer setContents:(id)[maskImg CGImage]];
CGRect frma = maskContainer.frame;
frma.size.width = self.frame.size.width;
frma.size.height = self.frame.size.height;
maskContainer.frame = frma;
[self.imageView.layer setMask:maskContainer];
Its messed up. The overall image starts fading on top.
Can anyone share their insight on the right way to mask?
You could set a drop shadow on your text to make is stand out even over a white background:
myLabel.layer.shadowOpacity = 0.8f;
myLabel.layer.shadowOffset = CGSizeMake(0, 0);
Easiest option is to adjust the alpha on the UILabel to the desired darkness in order to make the text stand out. If you do not want to hide the image and the image itself serves as a dark background, then set the alpha on the label to 0.
The best way to do this is to place the label in a uiview then create a gradient to apply as the background to the uiview. You can create the gradient as either an image with transparency or you can draw it in code. This will create a darkening effect on you bright image just behind the label so the text will pop.

UIView subview placement

I have a UIView that I am placing UIImageView's into, with each UIImageView being 16 pixels wide.
The query is if I add say 5 of the UIImageViews using addSubView, and the UIView is spec'd at 16 tall by 300 wide, is there any way to have the images in the view 'stack up' so to speak, so that the images are not on top of each other? Like adding image tags to a web page.
The easiest way I see of doing this is to keep a running tally of where you last placed an image, then increment by width, something like this:
-(void) addImage:(UIImage*)img toView:(UIView*)view
{
static CGRect curFrame = CGRectMake (0,0,16,16);
UIImageView* imgView = [[UIImageView alloc] initWithFrame:curFrame];
imgView.image = img;
[view addSubview:imgView];
curFrame.origin.x += 16;
}
This will have the images appear within your view from left to right
I think I understand your question correctly. You want all the images to line up in a row correct? You would need to set the frame of the UIImageView's view. The orgin will be where the top left of your image is(x,y coordinates inside the UIView that contains it) - so you would move that over 16 each time you add another image.

Resources