The project I'm working on in Xcode is done in landscape.
I may be doing something wrong, but I've had to rotate every image 270 degrees before adding them to my file.
NSString *strFromInt = [NSString stringWithFormat:#"%d",score];
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(gc, 1, 1, 1, 1);
NSString *str = (#"Score ");
UIFont *uif = [UIFont systemFontOfSize:40];
[strFromInt drawAtPoint:CGPointMake(150, 10) withAttributes:#{NSFontAttributeName:uif}];
[str drawAtPoint:CGPointMake(10, 10) withAttributes:#{NSFontAttributeName:uif}];
When I try including a score (in the above code), the text runs along the wall vertically.
Any way to fix this (preferably in a method that doesn't make me have to rotate all 47 of my images again)?
I suspect the issue is that you are using CoreGrphics to place everything on the screen. Using UILabel's etc. would do this for you as these are self contained views with logic behind them as apposed to to instruction the OS to draw the letters for you.
Is there a reason you can't use UIlabel ?
You can use UILable with clearColor. This will resolve your problem.
Related
I want to scale imageview at minimum size and even the image view is intractable when it's size is around 5*5 or something near.
In snapchat Image (sticker) is shrinking at very small size and even it can be intractable to change position and scale.
I have implemented Pan Pinch and Rotate gesture. And also make it resizable but not as like snapchat.
I want help to achieve this. Many thanks.
I'd suggest to write a custom class, extending UIView which contains an additional UIImageView. Hook the PinchGestureRecognizer to the UIView and then use their GestureRecognizers Delgeate Methods to resize the UIImageView. this way the tactility doesn't change.
to further optimize it you could initialize the UIView based on the size of the UIImageView and also scale it down to a certain minimum. That way It will feel more natural. Otherwise, if you start "too big" than you have a different issue.
When you pinch the image,apply the below code
NSData *postData = UIImageJPEGRepresentation(passYourImageHere, (double)(100-[25 doubleValue])/100);
NSInteger imgSizeBytes = [postData length];
double imgSizeKBytes = ceil((double)imgSizeBytes / 1024);
NSString *strBytes;
if(imgSizeKBytes > 1024) {
double imgSizeMBytes = (double)imgSizeKBytes / 1024;
strBytes = [NSString stringWithFormat:#"%.1f MB", imgSizeMBytes];
}
else {
strBytes = [NSString stringWithFormat:#"%d KB", (int)imgSizeKBytes];
}
imgView.image = [UIImage imageWithData:postData scale:0.1];
lblSize.text = [NSString stringWithFormat:#"The shrinked size will be%#", strBytes];
UITextField in iOS 8.1.X have different vertical text alignment between editing and not editing mode when using some fonts like Helvetica Neue Light 17:
I have a sample project here.
Is there a workaround that I don't need to create a custom text field?
The main problem is that when using Dynamic Type, so the font can changes in runtime.
Anyway I opened a radar rdar://19374610.
Just stumbled across the same issue and decided to 'debug' a little. Basically I just plotted values for various fonts (cap height, point size, preferred height, available height, the distance the text moved) and noticed a pattern.
The reason the text moves up because it is rendered in two completely different ways: the non-editing version is rendered using -drawRect: (you can even override the hook), the editing version is rendered by a so-called UIFieldEditor. This one appears to ceil the text height regardless of whether or not you're on a Retina device and centers it afterwards. On Retina devices though, you should always ceil(scalar * scale) / scale to align on pixels. Hence iOS assumes a greater text height than needed, and moves it a little further up to keep it centered. Funnily enough, the rendering of static text and UIFieldEditor differ.
To fix the issue, subclass UITextField and override -editingRectForBounds:. Here you will want to take the non-editing-rect ('text rect') and account for the shift Apple is going to perform in advance.
- (CGRect)editingRectForBounds:(CGRect)bounds
{
if (UIDevice.currentDevice.systemVersion.integerValue != 8) return [self textRectForBounds:bounds];
CGFloat const scale = UIScreen.mainScreen.scale;
CGFloat const preferred = self.attributedText.size.height;
CGFloat const delta = ceil(preferred) - preferred;
CGFloat const adjustment = floor(delta * scale) / scale;
CGRect const textRect = [self textRectForBounds:bounds];
CGRect const editingRect = CGRectOffset(textRect, 0.0, adjustment);
return editingRect;
}
Edit: I just tested the code on older OS versions, including 8.0. On iOS 7.x, everything appears to be fine, iOS 8.0 contains the bug already. We cannot predict the future, so for now I would only include the fix for iOS 8.x, hopefully Apple fixes the problem in iOS 9 themselves.
Another Edit: This code makes the editing text appear at the same location as its static counterpart. If you want to control them separately (which Apple thinks makes sense, since they offer both -textRectForBounds: and -editingRectForBounds:), you may want to replace [self textRectForBounds:bounds] with [super editingRectForBounds:bounds]. If you want to implement this fix in a category using swizzling, you certainly should use the super version.
This bug is font dependant so I will go with a solution that set the style of the attributed string to compensate this.
An example to fix this for the first textField with the Helvetica Neue Light and size 17:
Suppose the view controller is the delegate of the firstTextField
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSDictionary *style = #{
NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue-Light"
size:17],
NSParagraphStyleAttributeName : [NSParagraphStyle defaultParagraphStyle],
NSBaselineOffsetAttributeName: #(0.4)
};
_firstTextField.attributedText = [[NSAttributedString alloc] initWithString:_firstTextField.text
attributes:style];
}
-(void)textFieldDidBeginEditing:(UITextField *)textField {
NSDictionary *style = #{
NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue-Light"
size:17],
NSParagraphStyleAttributeName : [NSParagraphStyle defaultParagraphStyle],
NSBaselineOffsetAttributeName: #(0.0)
};
[_firstTextField setTypingAttributes: style];
}
The key part is when you set the NSBaselineAlignment from when you present the textField to when you are editing it. Also I checked what happen when the font is double size (with a textField big enough) and the NSBaselineOffset is still the same to avoid the jumping effect.
I was going through the SpriteKit documentation by Apple and came across a really useful feature that I could use when programming my UI. The problem is I can't get it to work.
Please see this page and scroll down to "Resizing a Sprite" - Apple Docs
I have literally copied the image dimensions and used the same code incase I was doing something wrong. But I always end up with a stretched looking image rather than the correct "end caps" staying the same scale.
I am referring to this code:
SKSpriteNode *button = [SKSpriteNode spriteWithImageNamed:#"stretchable_button.png"];
button.centerRect = CGRectMake(12.0/28.0,12.0/28.0,4.0/28.0,4.0/28.0);
What am I doing wrong? Is there a step I have missed?
EDIT:
Here is the code I have been using. I stripped it of my button class and tried to use it with an SKSPriteNode but still the problem persists. I also changed the image just to make sure it wasnt that. The image im using is a 32x32 at normal size.
SKSpriteNode *button = [SKSpriteNode spriteNodeWithImageNamed:#"Button.png"];
[self addChild:button];
button.position = ccp(200, 200);
button.size = CGSizeMake(128, 64);
button.centerRect = CGRectMake(9/32, 9/32, 14/32, 14/32);
The .centerRect property works as documented if you adjust the sprites .scale property.
Try:
SKTexture *texture = [SKTexture textureWithImageNamed:#"Button.png"];
SKSpriteNode *button = [[SKSpriteNode alloc] initWithTexture:texture];
button.centerRect = CGRectMake(9/32, 9/32, 14/32, 14/32);
[self addChild:button];
button.xScale = 128.0/texture.size.width;
button.yScale = 64.0/texture.size.height;
9/32 is integer division, so the result passed to CGRectMake is zero. Ditto the other three parameters. If you use floating point literals like the example you cite, you might get better results.
Here's a refresh of how exactly this works. By the way, my image size width is 48 pixels and height is 52 pixels, but this doesn't matter at all. Any image can be used:
SKSpriteNode *button = [SKSpriteNode spriteNodeWithImageNamed:#"Button.png"];
//(x, y, width, height). First two values are the four corners of the image that you DON'T want touched/resized (They will just be moved).
//The second two values represent how much of images width & height you want cut out & used as stretching material. Cut out happens from the center of the image.
button.centerRect = CGRectMake(20/button1.frame.size.width, 20/button1.frame.size.height, 5/button1.frame.size.width, 15/button1.frame.size.height);
button.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); //Positions sprite in the middle of the screen.
button.xScale = 4; //Resizes width (This is all I needed).
//button.yScale = 2; //Resizes height (Commented out because I didn't need this. You can uncomment if the button needs to be higher).
[self addChild:button];
Read the section called "Resizing a Sprite" in this document: https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9-SW10
'Figure 2-4 A stretchable button texture' demonstrates how the (x, y, width, height) works.
Based on rwr's answer here is a working init method for a SKSpriteNode. I use this in my own game. Basically you make insets of 10px all around the the output image. And then call it like this:
[[HudBoxScalable alloc] initWithTexture:[atlas textureNamed:#"hud_box_9grid.png"] inset:10 size:CGSizeMake(300, 100) delegate:(id<HudBoxDelegate>)clickedObject];
-(id) initWithTexture:(SKTexture *)texture inset:(float)inset size:(CGSize)size {
if (self=[super initWithTexture:texture]) {
self.centerRect = CGRectMake(inset/texture.size.width,inset/texture.size.height,(texture.size.width-inset*2)/texture.size.width,(texture.size.height-inset*2)/texture.size.height);
self.xScale = size.width/texture.size.width;
self.yScale = size.height/texture.size.height;
}
return self;
}
I have the following problem - I need to create two UI labels along side one another as in the screen shot below -
The UI label containing the special offers text is dynamic and needs to adjust to the width of the containing text and also if possible display the slanted orange background with the relevant padding -
I'm predominantly a Front-end dev - so with CSS i'd use a long background image that aligns to the right of the label and pad accordingly - but I have no idea how to approach this in objective C - can anyone offer any advice?
This is not a drop-in solution, but perhaps helps you find it (assuming you don't use Auto Layout):
You need a UIImageView for the background and a UILabel for the text
Use a tileable/strechable image (probably with cap insets) for the background (see [UIImage resizableImageWithCapInsets:resizingMode:])
Set the text on your label
Call [label sizeToFit] to resize the label to exactly fit the contained text
Resize the image view depending on the label's size (e.g. imageView.frame = CGRectInset(label.frame, -10, -10), which would make your image view 10pt larger than the label on all sides).
With Auto Layout you'd just define the appropriate constraints between the label and the image view and rely on the label's "intrinsic content size" - should be quite easy.
You could always shrink the text when it gets to long for the label, go into your view controller, click on the label that you would like to shrink when the text gets too long, then, go down to Autoshrink under Label in the attributes inspector. Change it from fixed font size to minimum font size, then I recommend putting 6 to 8 as the lowest font size. This is going to be the LOWEST font size though, so if XCode can make the label fit while making the font size 9, yet the lowest is 7, it will do it.
Or, you could get the length of the string with
int *stringLength = [myString length]
which counts spaces too, then, change the orange square with
orangeBoxImageView.frame = CGRectMake(0, 0, resizedWidth, resizedHeight);
so you could do something like this with your code:
if(stringLength == 15{
orangeBoxImageView.frame = CGRectMake(0, 0, 15, 5);
}
I hope this could help you
CGFloat rect = [YOURSTRING
boundingRectWithSize: (CGSize){ labelWidth, CGFLOAT_MAX }
options: NSStringDrawingUsesLineFragmentOrigin
attributes: #{ NSFontAttributeName : labelFont };
context: nil];
This assumes numberOfLines = 0.
What you want to use is UILabel -sizeToFit inherited from UIView. You should be able to figure out the rest from there.
Find the size of the containing text with
[text sizeWithFont:font constrainedToSize:CGSizeMake(width, height) lineBreakMode:NSLineBreakModexx]
Once you have that, you can manipulate the size of the label accordingly.
Hope this helps
For the background I'd create a subclass of UILabel that overrides drawInRect:, such as this example that simply draws a rectangle with the size of the label
-(void) drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
Rather than drawing a rectangle, you should create a path with the shape that you need and fill that. See here for more info:
http://weblog.invasivecode.com/core-graphics
I don't know how you've created your label, but if it's done properly with autolayout it'll have the correct width automagically. See here:
http://www.raywenderlich.com/20881/
Tim
I've been looking for a solution to this problem for a while, and no one seems to have come across a similar issue.
Basically I have multiple UITextViews that I use to detect addresses, urls, phone numbers, etc (anything that can be detected via UIDataDectorTypeAll) from some EKEvent.notes. I then add these UITextViews as subviews of a UIScrollView.
Now, for some reason or another, once the UITextView detects an address or a phone number and becomes an actionable target, it will randomly draw with a font 2x its specified font!
I've setup tests to just redraw my views if I tap. When the UITextView is added to the view initially, I can see in black the proper text. Then it does its detection deal and becomes a actionable target. Sometimes it stays the proper size, sometimes it draws at 2x font (but still in proper frame, thus it gets clipped).
It's very straight forward, but here's my code below. All variable are correct values, frame is correct, text is correct, everything is correct and about 50% of the time it draws correct. Its just that other 50% of the time it becomes (apparently) 2x font! Any help is greatly appreciated!
UITextView *locationTextView = [[UITextView alloc] init];
locationTextView.dataDetectorTypes = UIDataDetectorTypeAll;
locationTextView.text = location;
locationTextView.font = [UIFont fontWithName:#"AvenirNext-Regular" size:17];
locationTextView.editable = NO;
locationTextView.userInteractionEnabled = YES;
locationTextView.contentInset = UIEdgeInsetsMake(-8,-8,-8,-8);
locationTextView.frame =CGRectMake(kBufferLeft, daySize.height, kBufferDayViewTextWidth, locationSize.height);
[scrollView addSubview:locationTextView];
Correct: http://i.imgur.com/3pJ43kj.jpg
Incorrect: http://i.imgur.com/DLq4gco.jpg
(Not allowed to post images yet, sorry.)
Same exact code produced both effect. Thank you for your time.
Cheers!
EDIT: I went with TTTAttributedLabels to fix this issue.
github.com/mattt/TTTAttributedLabel
You can set font at <UITextField> delegate.
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
locationTextView.font = [UIFont fontWithName:#"AvenirNext-Regular" size:17];
}
I had the same problem because I was using a custom line breaking (layoutManager:shouldBreakLineByWordBeforeCharacterAtIndex:). Had to disable that.