ios7 CGRect property not found on object - uiimage

I tried using the following code to NSLog the dimensions of an UIImage but am receiving a warning that "Property 'theImage' not found on object of type ...." What am I doing wrong?
UIImage *theImage = [UIImage imageNamed:#"my_image.jpg"];
CGRect imageContent = self.theImage.bounds;
CGFloat imageWidth = imageContent.size.width;
CGFloat imageHeight = imageContent.size.height;
NSLog(#"Size of my Image => %f, %f ", imageWidth, imageHeight);

You should code like this:
UIImage *theImage = [UIImage imageNamed:#"my_image.jpg"];
CGSize imageContent = theImage.size;
CGFloat imageWidth = imageContent.width;
CGFloat imageHeight = imageContent.height;
NSLog(#"Size of my Image => %f, %f ", imageWidth, imageHeight);

It means exactly what it says; whichever class you've put that code into doesn't have a property named theImage. You probably instead meant:
CGSize imageContent = theImage.size;
CGFloat imageWidth = imageContent.width;
CGFloat imageHeight = imageContent.height;
Use the self. notation to access properties of that instance of the class. Local variables are a separate concept and so are accessed in a separate way. Instance variables have the same lifetime as the instance of the class. Local variables have only the lifetime of the enclosing scope (the method in this case).
In addition, as per user3779315, UIImage has a size but does not have bounds. That's because it has no origin. It's not part of any sort of layout hierarchy; it's standalone.

Related

tvOS adjustsImageWhenAncestorFocused crops image collection view cell

When you use .imageView.adjustsImageWhenAncestorFocused you get your image scaled, you get it bigger on focus. The image goes beyond it's bounds. That means that you can't see full image - it's coped on all sides.
You have:
You want:
If you want it work from the box, you need to remember to reserve Focused/Safe zone size (from documentation) when you create your image.
In my case I have my images from server and I can't edit them.
What worked for me - it's to redraw image right before setting:
UIImage *oldImage = [UIImage imageNamed:#"example"];
CGFloat width = cell.imageView.frame.size.width;
CGFloat height = cell.imageView.frame.size.height;
CGSize newSize = CGSizeMake(width, height);
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = oldImage.CGImage;
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
CGContextRef resizeContext = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(resizeContext, kCGInterpolationHigh);
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
CGContextConcatCTM(resizeContext, flipVertical);
CGContextDrawImage(resizeContext, newRect, imageRef);
CGImageRef newImageRef = CGBitmapContextCreateImage(resizeContext);
UIImage *newImageResized = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = newImageResized;
});
It's nor necessary to redraw in this way, but the point is you need to draw your UIImage again in order to have your image displayed properly.
Code from here.

Core Plot CPTBorderedLayer not animating

I have a CPTPlotSpaceAnnotation whose contentLayer property is a CPTBorderedLayer object. I'm trying to animate the CPTBorderedLayer object with the following:
CGRect originalBounds = annotation.contentLayer.bounds;
CGRect expandedBounds = annotation.contentLayer.bounds;
expandedBounds.size.width *= 1.5f;
expandedBounds.size.height *= 1.5f;
CABasicAnimation* boundsAnimation = [CABasicAnimation animationWithKeyPath:#"bounds"];
boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
boundsAnimation.fromValue = [NSValue valueWithCGRect:originalBounds];
boundsAnimation.toValue = [NSValue valueWithCGRect:expandedBounds];
boundsAnimation.duration = 1.0f;
boundsAnimation.removedOnCompletion = NO;
[annotation.contentLayer addAnimation:boundsAnimation forKey:#"bounds"];
But this isn't animating. Setting the bounds directly to expandedBounds works, but it won't animate. Thoughts?
The issue was that I had the collapsesLayers property on my CPTGraphHostingView set to YES. Setting it to NO fixed the issue.

Auto-Resizing of NSTextView and/or NSScrollView

I have an NSTextView inside an NSView (which is being used by a NSPopover, don't know if that is relevant) that I'm trying to resize automatically and programmatically (cf caption).
I have been struggling with a lot of stuff, namely :
Looking at NSLayoutManager and usedRectForTextContainer that give me aberrant size values
(usedRectForTextContainer : {{0, 0}, {0.001, 28}})
Modifying NSScrollView frame, [NSScrollView contentView], [NSScrollView documentView]
Getting rid of AutoLayout
I reached the point where I can resize my scollview and my Popover, but I can't get the actual height of the text inside the NSTextView.
Any kind of help would be appreciated.
-(void)resize
{
//Get clipView and scrollView
NSClipView* clip = [popoverTextView superview];
NSScrollView* scroll = [clip superview];
//First, have an extra long contentSize and ScrollView to test everything else
[popover setContentSize:NSMakeSize([popover contentSize].width, 200)];
[scroll setFrame:(NSRect){
[scroll frame].origin.x,[scroll frame].origin.y,
[scroll frame].size.width,155
}];
NSLayoutManager* layout = [popoverTextView layoutManager];
NSTextContainer* container = [popoverTextView textContainer];
NSRect myRect = [layout usedRectForTextContainer:container]; //Broken
//Now what ?
}
I still have no idea why I can't use [layout usedRectForTextContainer:container], but I managed to get the NSTextView's height by using :
-(void)resize
{
//Get glyph range for boundingRectForGlyphRange:
NSRange range = [[myTextView layoutManager] glyphRangeForTextContainer:container];
//Finally get the height
float textViewHeight = [[myTextView layoutManager] boundingRectForGlyphRange:range
inTextContainer:container].size.height;
}
Here is some functional code that I have tested myself for swift. usedRectForTextContainer is not broken it just is set lazily. To set it i call glyphrangefortextcontainer
I found the answer here: http://stpeterandpaul.ca/tiger/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html
let textStorage = NSTextStorage(string: newValue as! String)
let textContainer = NSTextContainer(size: NSSize(width: view!.Text.frame.width, height:CGFloat.max))
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = NSLineBreakMode.ByWordWrapping
textStorage.font = NSFont(name: "Times-Roman", size: 12)
layoutManager.glyphRangeForTextContainer(textContainer)
let rect = layoutManager.usedRectForTextContainer(textContainer)
Swift.print(rect)
The documentation also suggest that is the the case:

UITextView, setContentOffset and missing bottom part

For some strange reason, my UITextView's text appears cropped when the scrollofset is set.
Here's what it looks like:
This happens after doing:
textview.contentInset = UIEdgeInsetsZero;
[textview setContentOffset:CGPointMake(0, startypos + offset_yshift) animated:NO];
I tried manually setting contentSize.height, but that introduced another strange behavior, where the content offset seems to be ignored..
''Edit'': This is the code used to instantiate the textfield:
CGRect myImageRect = CGRectMake(-50.0f, -50.0f, 40.0f, 40.0f);
textview = [[UITextView alloc] initWithFrame: myImageRect];
textview.autocapitalizationType = UITextAutocapitalizationTypeNone;
[textview setScrollEnabled:YES];
textview.hidden = YES;
textview.contentInset = UIEdgeInsetsZero;
textview.opaque = NO;
textview.backgroundColor = [UIColor clearColor];
textview.textColor = [UIColor colorWithWhite:1 alpha:1];
textview.textAlignment = NSTextAlignmentCenter;
textview.frame = CGRectMake(0, 0, 250, 30);
textview.scrollEnabled = NO;
And the "update" code that checks the content positioning every frame:
// setting the actual size here
UITextPosition * pos = [textview positionFromPosition: textview.endOfDocument offset:nil];
CGRect therect = [textview caretRectForPosition:pos];
CGRect frame = textview.frame;
if([textview.text length] == 0){
frame.size.height = 30;
} else {
frame.size.height = therect.origin.y + therect.size.height;
}
// and here, we're changing the frame variable's height to max to 50
if(frame.size.height > 50){
frame.size.height = 50;
}
frame.size.width = desiredwidth; // some other variable
textview.frame = frame;
/*
... snip, unrelated code ...
*/
// later on
textview.contentInset = UIEdgeInsetsZero;
[textview setContentOffset:CGPointMake(0, startypos + offset_yshift) animated:NO];
As you can imagine, the setContentOffset bit there is what's causing the issue.
What is going on?
please try this from prev post
CGPoint offset = CGPointMake(0, self.textView.contentSize.height - self.textView.frame.size.height);
[self.textView setContentOffset: CGPointMake(0,0) animated:NO];
or
[self.textView setContentOffset:bottomOffset animated:YES];
[post]: UITextView contentOffset on iOS 7 "prev post"\
I ran into a very similar issue in iOS7 with UITextField - looks almost exactly the same. Mine had to do with content insets as well.
The solution (for me) - was to eliminate the UITextField from nib/storyboard and instantiate it and add it to the view purely from code. Behavior worked as expected afterwards.
I don't know what was up other than it probably being a iOS7 / XCode 5 bug... Curious to know if that solves it for you too.
My thougts would be, to adjust the size of the UITextView based on its content.
Like asked here: how-do-i-size-a-uitextview-to-its-content
Code taken from jhibberd ´s answer
- (void)textViewDidChange::(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
}

NSImage size not real size with some pictures?

I see that sometimes NSImage size is not real size (with some pictures) and CIImage size is always real. I was testing with this image.
This is source code which I wrote for testing:
NSImage *_imageNSImage = [[NSImage alloc]initWithContentsOfFile:#"<path to image>"];
NSSize _dimensions = [_imageNSImage size];
[_imageNSImage release];
NSLog(#"Width from CIImage: %f",_dimensions.width);
NSLog(#"Height from CIImage: %f",_dimensions.height);
NSURL *_myURL = [NSURL fileURLWithPath:#"<path to image>"];
CIImage *_imageCIImage = [CIImage imageWithContentsOfURL:_myURL];
NSRect _rectFromCIImage = [_imageCIImage extent];
NSLog(#"Width from CIImage: %f",_rectFromCIImage.size.width);
NSLog(#"Height from CIImage: %f",_rectFromCIImage.size.height);
And output is:
So how that can be?? Maybe I'm doing something wrong?
NSImage size method returns size information that is screen resolution dependent. To get the size represented in the actual file image you need to use an NSImageRep. You can get an NSImageRep from an NSImage using the representations method. Alternatively you can create a NSBitmapImageRep subclass instance directly like this:
NSArray * imageReps = [NSBitmapImageRep imageRepsWithContentsOfFile:#"<path to image>"];
NSInteger width = 0;
NSInteger height = 0;
for (NSImageRep * imageRep in imageReps) {
if ([imageRep pixelsWide] > width) width = [imageRep pixelsWide];
if ([imageRep pixelsHigh] > height) height = [imageRep pixelsHigh];
}
NSLog(#"Width from NSBitmapImageRep: %f",(CGFloat)width);
NSLog(#"Height from NSBitmapImageRep: %f",(CGFloat)height);
The loop takes into account that some image formats may contain more than a single image (such as TIFFs for example).
You can create an NSImage at this size by using the following:
NSImage * imageNSImage = [[NSImage alloc] initWithSize:NSMakeSize((CGFloat)width, (CGFloat)height)];
[imageNSImage addRepresentations:imageReps];
NSImage size method return size in points. To get size represented in pixels you need inspect NSImage.representations property that contains an array of NSImageRep objects with pixelWide/pixelHigh properties and simple change size NSImage object:
#implementation ViewController {
__weak IBOutlet NSImageView *imageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
NSImage *image = [[NSImage alloc] initWithContentsOfFile:#"/Users/username/test.jpg"];
if (image.representations && image.representations.count > 0) {
long lastSquare = 0, curSquare;
NSImageRep *imageRep;
for (imageRep in image.representations) {
curSquare = imageRep.pixelsWide * imageRep.pixelsHigh;
if (curSquare > lastSquare) {
image.size = NSMakeSize(imageRep.pixelsWide, imageRep.pixelsHigh);
lastSquare = curSquare;
}
}
imageView.image = image;
NSLog(#"%.0fx%.0f", image.size.width, image.size.height);
}
}
#end
Thanks to Zenopolis for the original ObjC code, here's a nice concise Swift version:
func sizeForImageAtURL(url: NSURL) -> CGSize? {
guard let imageReps = NSBitmapImageRep.imageRepsWithContentsOfURL(url) else { return nil }
return imageReps.reduce(CGSize.zero, combine: { (size: CGSize, rep: NSImageRep) -> CGSize in
return CGSize(width: max(size.width, CGFloat(rep.pixelsWide)), height: max(size.height, CGFloat(rep.pixelsHigh)))
})
}
If your file contains only one image, you can just use this :
let rep = image.representations[0]
let imageSize = NSSize(width: rep.pixelsWide, height: rep.pixelsHigh)
image is your NSImage, imageSize is the image size in pixels.
Copied and updated here: https://stackoverflow.com/a/13228091/3608824
NSImage's size param returns size information dependent to screen resolution and scaling configuration.
Real size of image you can get with the following extension:
extension NSImage {
var sizeReal: NSSize {
guard representations.count > 0 else { return NSSize(width: 0, height: 0) }
let rep = self.representations[0]
return NSSize(width: rep.pixelsWide, height: rep.pixelsHigh)
}
}

Resources