How do I put an RTLabel on an iOS image? - ios

I am trying to use https://github.com/honcheng/RTLabel to get a rich text label, but my immediate goal is to display "Hello, world!"
My code is:
UIImageView *noteImage = [[UIImageView alloc] initWithFrame:bounds];
noteImage.image = image;
[self.view addSubview:noteImage];
CJSHCardView *noteView = [[CJSHCardView alloc] initWithImage:image];
[noteView setFrame:CGRectMake(100 * i, 20, 100 * scale, 100 * scale)];
noteView.transform = CGAffineTransformScale(noteView.transform, scale_x, scale_y);
NSString *text = #"Hello, world!";
RTLabel *label = [[RTLabel alloc] initWithFrame:CGRectMake(100 * i, 20, 100 * scale, 100 * scale)];
[noteImage addSubview:label];
[label setText:text];
I tried both noteImage and noteView in the second-to-last line. The rectangle has the same dimensions as the original image, which is displaying correctly. However, none of the approaches I've tried seem apt to display a label on top of the noteImage / noteView as backgrounds.
What is an appropriate way to get a label (preferably one that supports rich text) to display on top of an image meant to serve as background for it?

iOS 7's UILabel supports attributed strings, so unless you need to target an earlier version, I suggest simply building your UI in interface builder and setting the attributed text as needed in your code.

Related

iOS Setting text background color in UILabel (with rounded rectangle shape)

I need to create something like this.
One of the way is to create like this. I can append image (for "PDF").
NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; attachment.image = [UIImage imageNamed:#"MyIcon.png"];
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *myString= [[NSMutableAttributedString alloc] initWithString:#"My label text"]; [myString appendAttributedString:attachmentString];
myLabel.attributedText = myString;
But I not sure whether it is good. Is there any alternative way? Can I highlight 'PDF' word with rounded background? I can easily set text background color with attributed string but it won't have rounded corner.
myLabel.backgroundColor = [UIColor redColor];
myLabel.layer.cornerRedius = 5.0;
myLabel.laayer.maskToBounds = YES;
I would embed the UILabel for PDF in another UIView with the desired background color, and round the corners using view.layer.cornerRadius. This way you can adjust the UILabel how you want within the rounded view.
If you round the corners on the UILabel, you risk having your text overlap the rounded edges.
Use RTLabel library to convert the HTML text. I have used it several times. It works. Here is link to the library and a sample code.
https://github.com/honcheng/RTLabel.
and then apply the css style you need
Hope I helped.

Set CALayer as SCNMaterial's diffuse contents

I've been searching all over the internet over the past couple of days to no avail. Unfortunately, the apple documentation about this specific issue is vague and no sample code is available (at least thats what I found out). What seems to be the issue you may ask...
I'm trying to set a uiview's layer as the contents of the material that is used to render an iPhone model's screen (Yep, trippy :P ). The iPhone's screen's UV mapping is set from 0 to 1 so that no issue persists in mapping the texture/layer onto the texels.
So, instead of getting this layer to appear rendered on the iPhone, same as left image, Instead, I get this rendered onto the iPhone like right image
Correct Render                                        Incorrect Render
Also note, that when I set a breakpoint and debug the actual iPhone node and view it in Xcode, a completely different render is shown and the layer gets half-fixed when I continue execution:
Now then... HOW do I fix this issue??? I've tried playing with the diffuse's contents transform matrix but nothing gets fixed. I've also tried resizing the UIView to 256x256 (since the UV seems to be 256x256 as shown in blender - the 3d modelling package), but that doesn't fix anything.
Here is the code for the layer:
UIView *screen = [[UIView alloc] initWithFrame:self.view.bounds];
screen.backgroundColor = [UIColor redColor];
UIView *temp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screen.bounds.size.width, 60)];
temp.backgroundColor = [UIColor colorWithRed:0 green:(112.f/255.f) blue:(235.f/255.f) alpha:1];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(temp.bounds, 40, 0)];
label.frame = CGRectOffset(label.frame, 40, 0);
label.textColor = [UIColor colorWithRed:0 green:(48.f/255.f) blue:(84.f/255.f) alpha:1];
label.text = #"Select Track";
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:30];
label.minimumScaleFactor = 0.001;
label.adjustsFontSizeToFitWidth = YES;
label.lineBreakMode = NSLineBreakByClipping;
[temp addSubview:label];
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0, temp.bounds.size.height - 2, temp.bounds.size.width, 2)];
separator.backgroundColor = [UIColor colorWithRed:0 green:(48.f/255.f) blue:(84.f/255.f) alpha:1];
[temp addSubview:separator];
[screen addSubview:temp];
screen.layer.contentsGravity = kCAGravityCenter;
Edit
What's even weirder is that if I capture a UIImage of the view using:
- (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
and use that as the diffuse's content... everything works out perfectly fine?! It's really weird and frustrating since the image's size is exactly the same as the uiview's...
Edit 2
I ended up just using an image of the view as the texture, which makes things much more static than I needed. I won't set this as the answer because I'll still be waiting for a correct fix to this issue even if it in a long time. So, if you have an answer and this topic has been opened for a long time, please bump it if you can. The documentation on this section is just so poor.
New post on an old thread, but this day-in-age, it's possible to set the UIView itself as SCNMaterialProperty (diffuse) contents. Intention to support this feature is communicated directly from SceneKit engineering at Apple, though the documentation has not yet been updated to reflect it.
To tied back to the original post, do not set a UIView.layer as material property contents; instead set contents to the UIView itself.
[Update: according to Lance's comment below, support for views may be getting worse rather than getting better.]
The SceneKit docs pretty strongly suggest that, while there are cases where you can use animated CALayers as material content, that doesn't include UIView layers:
SceneKit cannot use a layer that is already being displayed elsewhere (for example, the backing layer of a UIView object).
That suggests that if you want to make animated content for your material, you're better off with either Core Animation used entirely on its own or SpriteKit.

Separate detailTextLabel by an image

Im trying to do this:
The separator needs to dynamically change with the length of the label. This is what i have now
UIImageView *separator = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Shuffle"]];
separator.frame = CGRectMake(CGRectGetMaxX(cell.detailTextLabel.frame), CGRectGetHeight(cell.frame) / 2,200, 20);
[cell addSubview:separator];
The image is placed there but it doesn't dynamically change like I thought it would.
If you only want a •, simply set the label text to
cell.detailTextLabel.text = [NSString stringWithFormat:#"ARTIST: %# • LENGTH: %#", artistName, formattedTimeAsString];
Of course you might have to use NSLocalizedString in case you support more than one language

how to programmatically align a label to an x, y coordinate

below are some other properties of the label. obviously nstextalignmentleft is not what i'm going for. having trouble understanding where to enter coordinates.
self.lblTimer = [[UILabel alloc] init];
self.lblTimer.translatesAutoresizingMaskIntoConstraints = NO;
self.lblTimer.textAlignment = NSTextAlignmentLeft;
self.lblTimer.font = [UIFont systemFontOfSize:10];
self.lblTimer.textColor = [UIColor redColor];`self.lblTimer = [[UILabel alloc] init];
I think you're misunderstanding what textAlignment does. This simply controls the alignment within the label, not on the screen. If you want to position the label on screen you must change its frame property:
self.lblTimer.frame = CGRectMake(x,y,width,height);
As you've set self.lblTimer.translatesAutoresizingMaskIntoConstraints to NO I am guessing you want to use Auto Layout and if so, I highly recommend taking a look at Masonry.
An alternative is to set the frame property on the label with requires a CGRect where you give it the x and y coordinates as well as the width and height.

Make only part of a sentence a link (add selector)

so I am trying to implement the following. I have a view, which has a sentence. Only part of the sentence links to another view. This is what it looks like:
I am a cat. Learn More
The Learn More would be a link (blue in color), which when clicked would open another view.
Currently I am using a UILabel to write "I am a cat". I realize that the best way to add selectors is to use a button, so "Learn More" should be a button?
Is there any way to write this sentence out without using two different UIComponents?
If not, then how do I make the UILabel and the UIButton completely horizontally aligned with each other?
The following is my code for the label in -layoutSubviews:
CGSize labelSize = [_label.text sizeWithFont:_label.font constrainedToSize:bounds.size lineBreakMode:_label.lineBreakMode];
_label.frame = CGRectMake(0, 0, bounds.size.width - kMarginForText, labelSize.height);
_label.center = CGPointMake(horizontalCenter, CGRectGetMaxY(_previousLabel.frame) + kDistanceBetweenPreviousAndCurrentLabel);
And the code for the label itself.
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_label.text = "I am a cat";
_label.font = [UIFont systemFontOfSize:14];
_label.textAlignment = NSTextAlignmentCenter;
_label.numberOfLines = 0;
_label.lineBreakMode = UILineBreakModeWordWrap;
[self addSubview:_label];
Any help would be appreciated!
To answer your question about a single UIComponent, you could use a UILabel in conjunction with a UITapGestureRecognizer to create the intended effect. Granted this would make the whole label tappable... but having a bigger tap target area is almost never a bad thing.
In particular you would use an NSAttributedString to set the label text (NSAttributedString change color at end of string):
UILabel *label = [[UILabel alloc] init];
//Use initwithframe or setup your constraints after initialization here
label.attributedText = (your nsattributed string here)
Then to initialize the tap recognizer onto the UILabel you would do something like this:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(userDidTapLearnMore)];
label.userInteractionEnabled = YES;
[label addGestureRecognizer:tap];
What you want to do is to align them by their baselines, which you can easily do in Interface Builder by selecting them and choosing Editor > Align > Baselines, as shown in this illustration:

Resources