Exlusive touch in cameraoverlay view (of the camerapicker) in iOS? - ios

In my application, I added a cameraOverlayView to the camerapicker. It contains three subviews, two UIButtons and one UIImageView. The image is draggable. The buttons are used to change the image to another one.
When I touch a button, or the image, the tap-to-focus rect of the camera will always be displayed beneath (and the actual focus will change). Setting exclusiveTouch to YES on all three subviews doesn't change the behaviour.
Any idea, how i can stop the camerapicker from getting the touches of my buttons / subviews of my overlayview (but still getting the touches for touch-to-focus, switching cameras etc.)?
To give some more information. I'm using the following code, to allow camera interaction while having an overlayview, which subviews still get the touches.
// CameraOverlayView.m
[...]
// ignore touches on this view, but not on the subviews
-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
id hitView = [super hitTest:point withEvent:event];
if (hitView == self) return nil;
else return hitView;
}

There are a couple of ways to stop this that I found. None of the ways do exactly what I would like it to do. But tweaking it around should give you something usable.
1.) Disable camera control. cameraPickerController.showsCameraControls = NO; This will ultimately take down the touch to focus from the screen but it would take down other controls too.
2.) Control the hitTest in your overlayView and set those area to nil. This solution is very awkward but it works for me.
This is my overlayView that manages a face mask
- (id)initWithFrame:(CGRect)frame imagePicker: (UIImagePickerController *) imagepicker{
self = [super initWithFrame:frame];
if (self) {
faceMaskButton = [UIButton buttonWithType:UIButtonTypeCustom];
faceMaskButton.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:.2];
faceMaskButton.frame = CGRectMake(10, 10, 70, 35);
faceMaskButton.layer.borderColor = [[UIColor colorWithRed:0 green:0 blue:0 alpha:.6] CGColor];
faceMaskButton.layer.borderWidth = 1;
faceMaskButton.layer.cornerRadius = 17;
[faceMaskButton setImage:[UIImage imageNamed:#"Facemask button"] forState:UIControlStateNormal];
[faceMaskButton addTarget:self action:#selector(facemask) forControlEvents:UIControlEventTouchDown];
faceMaskButton.exclusiveTouch = YES;
faceMaskButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
[self addSubview:faceMaskButton];
loadingFacemask = NO;
overlayImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Camera Face Overlay"]];
overlayImage.frame = CGRectMake((self.bounds.size.width - 400)/2, (self.bounds.size.height - 400)/3, 400, 400);
overlayImage.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
overlayImage.alpha = 0.9f;
[self addSubview:overlayImage];
imagePickerController = imagepicker;
}
return self;
}
- (void) facemask{
if (!loadingFacemask) {
loadingFacemask = YES;
[UIView animateWithDuration:.3 animations:^{
overlayImage.alpha = overlayImage.alpha? 0:1;
faceMaskButton.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
} completion:^(BOOL finished) {
faceMaskButton.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:.2];
loadingFacemask = NO;
}];
}
}
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
if ((self.bounds.size.height - 44)<point.y){
return imagePickerController.view;
}
if (point.x < faceMaskButton.bounds.origin.x + faceMaskButton.bounds.size.width +10 && point.y < faceMaskButton.bounds.origin.y + faceMaskButton.bounds.size.height + 10) {
[self facemask];
return nil;
}
return self;
}
So if you get tweaking, this will work for you. I am still looking for the magic wand that make this work without all the hacks. No sign of it still :(

Related

In Objective-C, how can I change the property of an instance inside of class via UIControl?

This question is about the exercise 6.9 of iOS Programming 4th Edition.
I have a class that can draw concentric circles and respond to touches by changing its color randomly.
Here is the implementation of the view:
#implementation LTHypnosisView
- (instancetype) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self){
self.backgroundColor = [UIColor clearColor];
self.circleColor = [UIColor lightGrayColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
//Draw the circles
}
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
float red = (arc4random() % 100) /100.0;
float green = (arc4random() % 100) /100.0;
float blue = (arc4random() % 100) /100.0;
UIColor *randomColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
self.circleColor = randomColor;
}
- (void) setCircleColor:(UIColor *)circleColor{
_circleColor = circleColor;
[self setNeedsDisplay];
}
#end
Here is the implementation of the viewController:
#implementation LTHypnosisViewController
- (void) viewDidLoad{
CGRect screenRect = self.view.bounds;
LTHypnosisView *mainView = [[LTHypnosisView alloc] initWithFrame:screenRect];
[self addSubview:mainView]
NSArray *items = #[#"Red",#"Green",#"Blue"];
UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:items];
[segControl addTarget:self
action:#selector(change:)
forControlEvents:UIControlEventValueChanged];
segControl.frame = CGRectMake(10, 50, self.view.bounds.size.width-20, 60);
segControl.selectedSegmentIndex = 0;
segControl.backgroundColor = [UIColor whiteColor];
[self.view addSubview:segControl];
}
- (void) change:(UISegmentedControl*)sender{
switch (sender.selectedSegmentIndex) {
//How should I write here??
}
}
#end
I want to change the color of the concentric circles with the UISegmentedControl. Consequently I need a method within the viewController to change the _circleColor property of the LTHypnosisView instance. How can I do that?
A simple way, I'd make LTHypnosisView *mainView a property of the view controller, make setCircleColor public, and then in change: method call [self.mainView setCircleColor:myColor];
You could also do something more involved, like define a protocol on LTHypnosisView and set the view controller as the datasource. Whenever the change: method is called, call something like [mainView updateColor] and within updateColor have it read the color from it's datasource.

Objective-C highlight UIButton when selected / unselected

I have a UIButton inside a UIView, when the UIButton is selected I would like have a background colour of dark gray...is this possible?
UIView *toolbar = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 40, 160)];
[toolbar setBackgroundColor:[UIColor colorWithWhite: 0.70 alpha:0.5]];
toolbar.layer.cornerRadius = 5;
UIButton *penTool = [UIButton buttonWithType:UIButtonTypeCustom];
penTool.frame = CGRectMake(5, 0, 30, 30);
[penTool setImage:[UIImage imageNamed:#"pen-but" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
[penTool addTarget:self action:#selector(drawButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
penTool.autoresizingMask = UIViewAutoresizingNone;
penTool.exclusiveTouch = YES;
penTool.tag = 1;
[toolbar addSubview:penTool];
What if you can do this?
[button setBackgroundColor:[UIColor greenColor]
forState:UIControlStateSelected];
Let's give a great API for every state, not just selected, just like UIButton default API's ability to change image and title for every state.
BGButton.h
#import <UIKit/UIKit.h>
#interface BGButton : UIButton
- (void)setBackgroundColor:(UIColor *)backgroundColor
forState:(UIControlState)state;
#end
BGButton.m
#import "BGButton.h"
#implementation BGButton {
NSMutableDictionary *_stateBackgroundColor;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_stateBackgroundColor = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
/*
* If user set button.backgroundColor we will set it to
* normal state's backgroundColor.
* Check if state is on normal state to prevent background being
* changed for incorrect state when updateBackgroundColor method is called.
*/
if (self.state == UIControlStateNormal) {
[self setBackgroundColor:backgroundColor forState:UIControlStateNormal];
}
}
- (void)setBackgroundColor:(UIColor *)backgroundColor
forState:(UIControlState)state {
NSNumber *key = [NSNumber numberWithInt:state];
[_stateBackgroundColor setObject:backgroundColor forKey:key];
}
/*
* state is synthesized from other flags. So we can't use KVO
* to listen for state changes.
*/
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
[self stateDidChange];
}
- (void)setEnabled:(BOOL)enabled {
[super setEnabled:enabled];
[self stateDidChange];
}
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
[self stateDidChange];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
[self stateDidChange];
}
- (void)stateDidChange {
[self updateBackgroundColor];
}
- (void)updateBackgroundColor {
NSNumber *key = [NSNumber numberWithInt:self.state];
self.backgroundColor = [_stateBackgroundColor objectForKey:key];
}
#end
You can use it like the default UIButton API
BGButton *button = [[BGButton alloc] init];
[button setBackgroundColor:[UIColor greenColor]
forState:UIControlStateSelected];
[button setBackgroundColor:[UIColor blueColor]
forState:UIControlStateHighlighted];
[button setBackgroundColor:[UIColor orangeColor]
forState:UIControlStateDisabled];
Even if you use
button.backgroundColor = [UIColor redColor];
You will stay safe, it will be translated into
[button setBackgroundColor:[UIColor redColor]
forState:UIControlStateNormal];
if you have this code
[self.view addSubview:toolbar];
then just implement your button selector
-(void)drawButtonTapped:(UIButton*)button{
if (button.selected) {
button.backgroundColor = [UIColor clearColor];
button.selected = NO;
}else{
button.backgroundColor = [UIColor darkGrayColor];
button.selected = YES;
}
}
I don't know why guys would go through such trouble when we have this functionality built-in inside UIButton. All you need to do is use UIButtonTypeSystem That's all.
[UIButton buttonWithType:UIButtonTypeSystem]
Seriously, there's nothing more to it. Have a look at it's behavior in the screenshots.
INTERFACE BUILDER
RUN TIME
Want to change color, set tintColor to color of your choice.
ADVANTAGES
Covers titles with dynamic lengths. Not applied on all button width.
When selected, title color is transparent, your background can be seen through, try to use an image as a background.
Let's hope you have at least iOS7 as deployment target. UIButtonTypeSystem was introduce with revised UI design guidelines of iOS7 and has been there for almost 3 years.
Good Luck!
I used a UIButton subclass here:
#import "CustomButton.h"
#interface CustomButton()
#property (nonatomic,strong) UIColor *originalColor;
#end
#implementation CustomButton
- (void)didMoveToSuperview
{
self.originalColor = self.superview.backgroundColor;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.superview.backgroundColor = [UIColor grayColor];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
if ([self hitTest:location withEvent:nil]) {
self.superview.backgroundColor = [UIColor grayColor];
self.originalColor = self.superview.backgroundColor;
}
else
{
self.superview.backgroundColor = self.originalColor;
}
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.superview.backgroundColor = self.originalColor;
}
#end
If you subclass your button from this class, It should give you the desired effect. This also gives you the highlight effect. If you wish you can disable it by removing the line on touchesBegan.
Just try to Override the UIButton with the following Method...
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
self.backgroundColor = [UIColor darkGray];
}
}
I think you'll be want to change the selectedImage for flexibility not the background.
Add another image (e.g. pen-but-selected) in the project. Add this 2nd line for setImage:
[penTool setImage:[UIImage imageNamed:#"pen-but-selected" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateSelected];
- (void)drawButtonTapped:(UIButton *)button {
button.selected = !button.selected;
}
If you still want to change background color. #jamil's answer would work. Make sure the buttonImage has transparent part so you can see the buttonBackground through the buttonImage.
Try using a boolean, or some other reference to the selection state of the button. You could also make use of a 'highlightColour' as well as the 'selectedColour' if you wanted closer control (should probably do this for better UX).
bool buttonIsSelected = false;
UIColor * selectedColour = [UIColor redColor];
UIColor * defaultColour = [UIColor blueColor];
UIButton * button = [UIButton new];
button.frame = CGRectMake(0,0,100,100);
button.backgroundColor = [UIColor redColor];
[self.view addSubview:button];
[button addTarget:self action:#selector(buttonTouchUp:) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(buttonTouchCancel:) forControlEvents:UIControlEventTouchCancel];
[button addTarget:self action:#selector(buttonTouchDown:) forControlEvents:UIControlEventTouchDown];
-(void)buttonTouchUp:(UIButton *)button {
if (buttonIsSelected){
buttonIsSelected = false;
button.backgroundColor = defaultColour;
} else {
buttonIsSelected = true;
button.backgroundColor = selectedColour;
}
}
-(void)buttonTouchCancel:(UIButton *)button {
button.backgroundColor = defaultColour;
if (buttonIsSelected){
button.backgroundColor = selectedColour;
}
}
-(void)buttonTouchDown:(UIButton *)button {
button.backgroundColor = selectedColour;
}
-(void)OnSelect:(UIButton*)button{
if (button.selected) {
button.backgroundColor = [UIColor blue];
button.selected = NO;
}else{
button.backgroundColor = [UIColor darkGrayColor];
button.selected = YES;
}
}
use the above this will work..
-(void)buttonTapped:(UIButton*)button{
button.selected =! button.selected;
if (button.selected)
button.backgroundColor = [UIColor grayColor];
else
button.backgroundColor = [UIColor clearColor];
}

how to set popover position horizontally

i am making an app i which i am using slider and on changing the position of slider value of slider is also sliding as well, now i am stuck that i want to set when i change postion of slider in horizontall form then i need to change that popover postion also in horizontall form. I am attaching a screen shot so that u people better understand it and this is my project link https://www.dropbox.com/s/n0fl34h6t8jlazn/CustomSlider.zip?dl=0,
below is my sample code on 1 view and i am changing my uislider class to anpopoverslider:
-(void)constructSlider {
_popupView = [[ANPopoverView alloc] initWithFrame:CGRectZero];
_popupView.backgroundColor = [UIColor clearColor];
_popupView.alpha = 0.0;
[self addSubview:_popupView];
}
and below is my ANpopoverslider
#import "ANPopoverSlider.h"
#implementation ANPopoverSlider
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self constructSlider];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self constructSlider];
}
return self;
}
#pragma mark - UIControl touch event tracking
-(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
// Fade in and update the popup view
CGPoint touchPoint = [touch locationInView:self];
// Check if the knob is touched. If so, show the popup view
if(CGRectContainsPoint(CGRectInset(self.thumbRect, -12.0, -12.0), touchPoint)) {
[self positionAndUpdatePopupView];
[self fadePopupViewInAndOut:YES];
}
return [super beginTrackingWithTouch:touch withEvent:event];
}
-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
// Update the popup view as slider knob is being moved
[self positionAndUpdatePopupView];
return [super continueTrackingWithTouch:touch withEvent:event];
}
-(void)cancelTrackingWithEvent:(UIEvent *)event {
[super cancelTrackingWithEvent:event];
}
-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
// Fade out the popup view
[self fadePopupViewInAndOut:NO];
[super endTrackingWithTouch:touch withEvent:event];
}
#pragma mark - Helper methods
-(void)constructSlider {
CGRect frame = CGRectMake(150, 230, 300.0, 10.0);
_popupView = [[ANPopoverView alloc] initWithFrame:frame];
_popupView.backgroundColor = [UIColor clearColor];
_popupView.alpha = 0.0;
[self addSubview:_popupView];
}
-(void)fadePopupViewInAndOut:(BOOL)aFadeIn {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
if (aFadeIn) {
_popupView.alpha = 1.0;
} else {
_popupView.alpha = 0.0;
}
[UIView commitAnimations];
}
-(void)positionAndUpdatePopupView {
CGRect zeThumbRect = self.thumbRect;
CGRect popupRect = CGRectOffset(zeThumbRect, 0, -floor(zeThumbRect.size.height * 1.5));
_popupView.frame = CGRectInset(popupRect, -20, -10);
_popupView.value = self.value;
}
#pragma mark - Property accessors
-(CGRect)thumbRect {
CGRect trackRect = [self trackRectForBounds:self.bounds];
CGRect thumbR = [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
return thumbR;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
and here is my popover class
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.font = [UIFont boldSystemFontOfSize:15.0f];
UIImageView *popoverView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sliderlabel.png"]];
[self addSubview:popoverView];
textLabel = [[UILabel alloc] init];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.font = self.font;
textLabel.textColor = [UIColor colorWithWhite:1.0f alpha:0.7];
textLabel.text = self.text;
textLabel.textAlignment = NSTextAlignmentCenter;
textLabel.frame = CGRectMake(0, -2.0f, popoverView.frame.size.width, popoverView.frame.size.height);
[self addSubview:textLabel];
}
return self;
}
-(void)setValue:(float)aValue {
_value = aValue;
self.text = [NSString stringWithFormat:#"%4.2f", _value];
textLabel.text = self.text;
[self setNeedsDisplay];
}
I tried the sample project and work with simple function
#property (strong, nonatomic) IBOutlet UISlider *slider; // make the getter and setter for Slider
#property (strong, nonatomic) IBOutlet UILabel *lblText; // make the getter and setter for label
- (void)viewDidLoad {
[super viewDidLoad];
// set verticical of UIslider
CGAffineTransform trans = CGAffineTransformMakeRotation(M_PI * 0.5);
self.slider.transform = trans;
// get the events of UISlider
[self.slider addTarget:self
action:#selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
}
// this method used for hide the label after changed the value
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(#"Slider did end sliding...");
[self.lblText removeFromSuperview];
}
// the slider value change method
- (IBAction)slider:(UISlider*)sender
{
// add the subview the lable to slider
[self.slider addSubview:self.lblText];
self.lblText.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"sliderlabel.png"]];
self.lblText.text = [NSString stringWithFormat:#"%4.2f",sender.value];
// change the label position depend upon slider move
self.lblText.center = CGPointMake(self.slider.value*self.slider.bounds.size.width,80);
[self.lblText setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
}
here I attached the sample project for UISlider the download link

iOS7 Selected Effect on Button Border

So I am new to iOS and I want some buttons with rounded boarders. I also want those borders to have the same effect as the text within the button when the button is selected.
Since roundRect buttons are no longer an object in iOS (or at least I couldn't find it and everywhere I read said that is was no more) I decided to write a custom class that extends UIButton. This is what I have:
- (void)drawRect:(CGRect)rect{
{
UIColor *blackColor = blackColor;
UIColor *transBlack = [blackColor colorWithAlphaComponent:(0.5)];
[self.layer setCornerRadius:10.0f];
[self.layer setBorderColor:[UIColor blackColor].CGColor];
[self.layer setBorderWidth:1.0];
if(self.isSelected){
[self.layer setBorderColor:(transBlack.CGColor)];
}
I'm not sure if I am using isSelected properly. I had an NSLog under it and it never seems to be executed no matter how many times I press the buttons.
Any help and suggestions of all kinds would be greatly appreciated. Thank you.
UIButton inherit from UIView, So you can use Layer's Methods...
Create new Object that Subclassing UIButton call it whatever you want, then implement the next Code:
In this sample i have UIButton subclass called PressedButton in the .m file:
#implementation PressedButton
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
//When the button is pressed the border color change to red
self.layer.borderColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5].CGColor;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//When the button is pressed the border color change back to black
self.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5].CGColor;
}
- (void)initialize{
self.layer.cornerRadius = 10.0f;
self.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5].CGColor;
self.layer.borderWidth = 2;
self.layer.masksToBounds = YES;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self initialize];
}
return self;
}
#end
*** I implemented the all init methods to be sure no matter where i set the button (storyboard or via Code its get the same init).
After that just configure your button custom class to your "Pressed Button class" and that's it
If you need more help be free to ask :)

Is this the way to create a custom UIView?

I've subclassed UIView so I can add multiple view of the same type to my project. The view is basically a rectangle with a radius, a picture in the left side and a piece of text on the right. Now don't get me wrong the code bellow works and all but i'm always asking myself "is this the way, or am I getting it really wrong".
1) I'm mixing CALayers with UILabels, is this ok?
2) Is the setUpView the way its done.
3) If this is ok, whats my best bet for letting the imageLayer respond to touch events?
4) Could I just ask a side question as well. As a part time beginner with only one basic app in the store am I been a bit picky. What I mean is, should I just make it work and crack on! What do you think?
#synthesize dateLabel = _dateLabel;
#synthesize nameLabel = _nameLabel;
#synthesize photo = _photo;
#synthesize roundRect= _roundRect;
#synthesize imageLayer = _imageLayer;
-(void)setUpView
{
//create the white rectangle
self.roundRect.frame = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height);
self.roundRect.cornerRadius = 15.0;
self.roundRect.backgroundColor = [UIColor clearColor].CGColor;
self.roundRect.borderColor = [UIColor whiteColor].CGColor;
self.roundRect.borderWidth = 2.0;
self.roundRect.masksToBounds = YES;
//create the photo
CGImageRef image = [self.photo CGImage];
self.imageLayer.frame = CGRectMake(0.0, 0.0, self.roundRect.frame.size.width*0.48, self.roundRect.frame.size.height);
self.imageLayer.borderColor = [UIColor whiteColor].CGColor;
self.imageLayer.borderWidth = 2.0;
self.imageLayer.masksToBounds = YES;
[self.imageLayer setContents:(__bridge id)image];
[self.imageLayer setContentsGravity:kCAGravityResizeAspectFill];
[self.imageLayer setContentsRect:CGRectMake(0.0,0.0,1.1,1.0)];
//create label
self.nameLabel.frame = CGRectMake(self.imageLayer.frame.size.width+5, self.roundRect.frame.size.height*0.05, self.roundRect.frame.size.width*0.48,self.roundRect.frame.size.height*0.35);
self.nameLabel.backgroundColor = [UIColor clearColor];
self.nameLabel.textAlignment = UITextAlignmentCenter;
self.nameLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
self.nameLabel.textColor = [UIColor whiteColor];
self.nameLabel.adjustsFontSizeToFitWidth =YES;
self.nameLabel.font = [UIFont fontWithName:#"Gill Sans" size:50.0];
[self.roundRect addSublayer:self.imageLayer];
[self.layer addSublayer:self.roundRect];
[self addSubview:self.nameLabel];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
-(void)setPhoto:(UIImage *)photo
{
_photo = photo;
[self setUpView];
}
-(void)setNameLabel:(UILabel *)nameLabel
{
_nameLabel = nameLabel;
[self setUpView];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.roundRect = [[CALayer alloc]init];
self.imageLayer = [[CALayer alloc]init];
self.nameLabel = [[UILabel alloc]init];
[self setUpView];
}
return self;
}
You could make this easier by using the Interface Builder. I would create a XIB with a UIView set to the size I want. Then add a label (nameLabel) and configure it how you like. You can use QuartzCore layers cornerRadius to set your rounded corners. Then you can use your subclass in the XIB and set it as the class type for the UIView. Not the file owner but the view. Then you can link your label as an outlet and you won't need to create it manually. You can remove some of the code above and still have your functionality and looks. I've learned to let the Interface Builder do the work when you can.
Hope this helps.

Resources