CAShapeLayer custom property is nil when drawInContext - uibezierpath

I denfined a custom layer,and declare a custom property,but it's not work when animation in -(void)drawInContext:(CGContextRef)ctx method
here is some code:
#interface ZBBProgressLayer : CAShapeLayer
#property (nonatomic, assign) CGFloat progress;
#property(nullable) CGColorRef progressColor;
#end
#implementation ZBBProgressLayer
+ (BOOL)needsDisplayForKey:(NSString *)key{
if ([key isEqualToString:#"progress"]/*progress 属性变化时,重绘*/) {
return YES;
}
return [super needsDisplayForKey:key];
}
-(void)dealloc{
[self removeAllAnimations];
}
#end
// ZBBRectProgressLayer
#interface ZBBRectProgressLayer : ZBBProgressLayer
#end
#implementation ZBBRectProgressLayer
-(void)drawInContext:(CGContextRef)ctx{
CGSize boundsSize = self.bounds.size;
CGFloat width = boundsSize.width * self.progress;
UIBezierPath *cutoutPath =[UIBezierPath bezierPathWithRect:CGRectMake(0,
0,
width,
boundsSize.height)];
CGContextSetFillColorWithColor(ctx,self.progressColor);
CGContextAddPath(ctx, cutoutPath.CGPath);
CGContextFillPath(ctx);
// NSLog(#"%# = %#\n",[self class],self);
}
#end
I use the layer like this:
-(void)setProgress:(CGFloat)progress animated:(BOOL)animated{
_progress = MIN(progress, 1);
if (animated) {
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"progress"];
animation.duration = kAnimationDurationTime;
animation.fromValue = #(_maskLayer.progress);
animation.toValue = #(_progress);
[_maskLayer addAnimation:animation forKey:#"progress"];
_maskLayer.progress = _progress;
}else{
_maskLayer.progress = _progress;
[_maskLayer performSelectorOnMainThread:#selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
}
}
but animated == true,custom layer.progressColor is nil,
animated == false,custom layer.progressColor is right.
source code : https://github.com/zhangbinbin5335/ZBBProgressView.git

Related

Change border color of buttons once pressed

I am trying to have the borders for the buttons change once buttons are pressed, here is how the code currently looks:
[m_btnEthinic addObject:btnEthnicity1];
[m_btnEthinic addObject:btnEthnicity2];
[m_btnEthinic addObject:btnEthnicity3];
[m_btnEthinic addObject:btnEthnicity4];
[m_btnEthinic addObject:btnEthnicity5];
[m_btnEthinic addObject:btnEthnicity6];
[m_btnEthinic addObject:btnEthnicity7];
[m_btnEthinic addObject:btnEthnicity8];
[m_btnEthinic addObject:btnEthnicity9];
for (UIButton* btn in m_btnEthinic) {
btn.layer.borderWidth = 1;
btn.layer.cornerRadius = 13;
btn.layer.borderColor = COLOR_GRAYBORDERBTN.CGColor;
[btn setBackgroundColor: COLOR_PURP];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]
With storyboard, you can do like this:
drag and place the button into viewcontroller
set the button Tag as per the buttons
drag the buttons into .h and create IBOutletCollection NSArray for buttons. Link all buttons into same outlet.
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *btn;
set IBAction common for all the buttons.
- (IBAction)btnActions:(UIButton *)sender;
once created IBAction, btnActions: method will be created in .m
-(IBAction) btnActions: (UIButton * ) sender {
for (UIButton * b in self.btn) {
//checking if already have borders for the buttons
if (b.layer.cornerRadius == 13) {
b.layer.borderWidth = 0;
b.layer.cornerRadius = 0;
}
//setting the borders for the selected button
if (b.tag == sender.tag) {
b.layer.borderWidth = 2;
b.layer.cornerRadius = 13;
b.layer.borderColor = [UIColor yellowColor].CGColor;
}
}
}
You can add a selector to you button, and use a BOOL property to track the button status and witch the color in the selector. If you have an array of buttons you will need an array of status flags. The code below should work (sorry for any typo. I am not in front of my computer at this time).
#property (strong, nonatomic) borderStatus;
-(void)viewDidLoad {
borderStatus = NO;
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)buttonPressed:(id)sender {
if(borderStatus){
((UIButton*)sender).layer.borderColor = [UIColor redColor];
borderStatus = NO;
} else {
((UIButton*)sender).layer.borderColor = [UIColor greenColor];
borderStatus = YES;
}
}
will, I guess you maybe need this. You can add two events for the buttons. So set border when the event UIControlEventTouchDown response, and recover it when the event UIControlEventTouchUpInsideresponse.
All this on my Github name 'T_yunButtonBorder' git#github.com:xmy0010/DemoForCSDN.git
Like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *m_btnEthinic = #[].mutableCopy;
for (int i = 0; i < 8; i++) {
UIButton *btnEthnicity = [UIButton buttonWithType:UIButtonTypeCustom];
[btnEthnicity setTitle:[NSString stringWithFormat:#"btn%d", i] forState:UIControlStateNormal];
btnEthnicity.frame = CGRectMake(50, 50 + 40 * i, 50, 20);
btnEthnicity.backgroundColor = [UIColor redColor];
[btnEthnicity addTarget:self action:#selector(btnEthnicityTouchDown:) forControlEvents: UIControlEventTouchDown];
[btnEthnicity addTarget:self action:#selector(btnEthnicityTouchUp:) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:btnEthnicity];
[m_btnEthinic addObject:btnEthnicity];
}
}
- (void)btnEthnicityTouchDown:(UIButton *)sender {
NSLog(#"down");
sender.layer.borderWidth = 2;
sender.layer.cornerRadius = 10;
sender.layer.borderColor = [UIColor greenColor].CGColor;
}
- (void)btnEthnicityTouchUp:(UIButton *)sender {
NSLog(#"up");
sender.layer.borderWidth = 0;
sender.layer.cornerRadius = 0;
}

trouble sending data to detailview

I am using collection view to get data from my server display some of it in a cell and then I have a segue to the destination view controller I got the image to update correctly but for some reason the text is not going to my UITextView
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//DetailSegue
if ([segue.identifier isEqualToString:#"DetailSegue"]) {
ICBCollectionViewCell *cell = (ICBCollectionViewCell *)sender;
NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
ICBDetailViewController *dvc = (ICBDetailViewController *)[segue destinationViewController];
path = [paths objectAtIndex:indexPath.row];
Path = [path objectForKey:#"path"];
title = [titles objectAtIndex:indexPath.row];
Title = [title objectForKey:#"title"];
sku = [SKUs objectAtIndex:indexPath.row];
Sku = [sku objectForKey:#"SKU"];
longDescrip = [longDescription objectAtIndex:indexPath.row];
LongDescrip = [longDescrip objectForKey:#"longDescrip"];
LongDescrip =#"Hello World";
NSLog(#"Descrip =%#",LongDescrip);
NSString *iconTitle =[NSString stringWithFormat:#"%#.png",Sku];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullPath = [docDir stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#",iconTitle]]; //add our image to the path
dvc.img = [[UIImage alloc] initWithContentsOfFile:fullPath];
dvc.title = Title;
//UITextView *descrip = (UITextView *)[cell viewWithTag:120];
[dvc.descrip setText:#"Hello"];
}
}
I am not sure if it has something to do with the fact that the object being sent to is a UITextView and I am sending it a String
or if I have something hooked up wrong
here is the .m and .h for the detailController also
the .h
#import <UIKit/UIKit.h>
#interface ICBDetailViewController : UIViewController
#property(weak) IBOutlet UIImageView *imageView;
#property (strong) UIImage *img;
#property(weak) IBOutlet UITextView *descrip;
#end
the .m
#import "ICBDetailViewController.h"
#interface ICBDetailViewController ()
#end
#implementation ICBDetailViewController
#synthesize imageView, img, descrip;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = self.img;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Hopefully somebody will see what I have missed for two days
after again reviewing it all I noticed i missed the outlet in the .h and forgot to set it show in the ViewDidLoad of the .m I also missed hooking upthe referencing outlet to my txtView

Annotation not dragging

MapPin.h :
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapPin : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic,readwrite,assign)CLLocationCoordinate2D coordinate;
- (id)initWithCoordinates:(CLLocationCoordinate2D)location placeName:(NSString *)placeName description:(NSString *)description;
-(void)setCoordinate:(CLLocationCoordinate2D)newCoordinate;
#end
and here's the MapPin.m
#import "MapPin.h"
#implementation MapPin
#synthesize coordinate;
-(NSString *)subtitle{
return nil;
}
-(NSString *)title{
return nil;
}
-(id)initWithCoordinates:(CLLocationCoordinate2D)location placeName:(NSString *)placeName description:(NSString *)description{
coordinate=location;
return self;
}
-(CLLocationCoordinate2D)location{
return coordinate;
}
-(void)setCoordinate:(CLLocationCoordinate2D)newCoordinate{
coordinate=newCoordinate;
}
#end
In the ViewController.h i've adopted the MKMapViewDelegate protocol.
and here's the ViewController.m :
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
MKPinAnnotationView *pin = (MKPinAnnotationView *)[self.MyMap dequeueReusableAnnotationViewWithIdentifier:#"myPin"];
if(pin == nil){
pin=[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"myPin"];
}
else{
pin.annotation=annotation;
}
pin.draggable=YES;
return pin;
}
//Add Location button
- (IBAction)AddPin:(id)sender {
CLLocationCoordinate2D center;
center.latitude=Locate.location.coordinate.latitude;
center.longitude=Locate.location.coordinate.longitude;
MKCoordinateRegion region;
region.center=center;
region.span.latitudeDelta=0.2f;
region.span.longitudeDelta=0.2f;
MapPin *myPin = [[MapPin alloc]initWithCoordinates:self.MyMap.centerCoordinate placeName:#"LoMinder!" description:#"Set Location for LoMinder!"];
[_MyMap addAnnotation:myPin];
}
//Dropping the pin:
- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)annotationView
didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState
{
//Region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
if (newState == MKAnnotationViewDragStateStarting)
{
[_MyMap setRegion:myRegion animated:YES];
}
if(newState == MKAnnotationViewDragStateDragging)
{
myRegion.center=annotationView.annotation.coordinate;
myRegion.span.latitudeDelta=0.2f;
myRegion.span.longitudeDelta=0.2f;
[_MyMap setRegion:myRegion animated:YES];
}
if(newState==MKAnnotationViewDragStateEnding)
{
arrived=self.MyMap.centerCoordinate;
center=annotationView.annotation.coordinate;
myRegion.center=center;
myRegion.span.latitudeDelta=0.2f;
myRegion.span.longitudeDelta=0.2f;
[_MyMap setRegion:myRegion animated:YES];
}
}
/////
I've also imported the MapPin.h into the ViewController.
When I run my app, I should press the Add Location button in ord er to get the annotation pin, I press the button, the annotation pin appears on the map, but the problem is that when i try to drag it, it seems to be un-draggable.
Please people some help.
Thank you :)
Solved by changing the title method in the MapPin.m
Make it return anything but nil.

cocos3d billboard paning with gestures

I want to pan the billboard using using gestures how can i do that, i have modified the DemoMashUp like this:
- (void)dragBy: (CGPoint) aMovement atVelocity: (CGPoint) aVelocity
{
if (selectedNode == dieCube || selectedNode == texCubeSpinner) {
[self rotate: ((SpinningNode*)selectedNode) fromSwipeVelocity: aVelocity];
}
if (selectedNode==marker) {
[self moveSelectedNode:marker fromSwipeMovement:aMovement];
}
}
- (void)stopDragging
{
selectedNode = nil;
}
- (void)moveSelectedNode:(CC3Billboard*) aNode fromSwipeMovement: (CGPoint) swipeMovement
{
aNode.location=cc3v(swipeMovement.x, swipeMovement.y, aNode.location.z);
}
but its not working and when i touch the billboard it disapears
i made a new method moveSelectedNode "DemoMashUpScene" like this :
-(void) touchEvent: (uint) touchType at: (CGPoint) touchPoint {
NSLog(#"\n\n*******************TOUCH EVEN CALLED************************\n\n");
switch (touchType) {
case kCCTouchBegan:
[self pickNodeFromTouchEvent: touchType at: touchPoint];
break;
case kCCTouchMoved:
if (selectedNode==marker||selectedNode==marker1||selectedNode==marker2||selectedNode==marker3||selectedNode==marker4||selectedNode==marker5)
{
[self moveSelectedNode:marker1 fromSwipeMovement:touchPoint];
}
break;
case kCCTouchEnded:
selectedNode = nil;
break;
default:
break;
}
lastTouchEventPoint = touchPoint;
lastTouchEventTime = now;
}
-(void) moveSelectedNode: (CC3Billboard*) aNode fromSwipeMovement: (CGPoint) swipeMovement {
CC3Vector vector= CC3VectorMake(swipeMovement.x * 3, swipeMovement.y * 3, 0);
aNode.location=cc3v(aNode.location.x, aNode.location.y, 0.0);
aNode.location=CC3VectorAdd(aNode.location,vector);
CCLOG(#"%#",aNode.name);
// NSLog(#"\n\n ******MOVING****%f_____%f*****____%f",vector.x,vector.y,vector.z);
}

Simulator does not show button text

I'm learning to build iPhone apps with XCode 4.5.2 and I noticed something strange. As you can see at the address http://i.stack.imgur.com/purI8.jpg the text inside one of the buttons is not displayed in the iOS6 simulator. I also tried to move the Enter button in the same line of 0 and -, but the text in all three buttons of the line disappeared. Anyone knows what's the cause of this problem and how to solve it? Here is the code:
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
#interface CalculatorViewController()
#property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber;
#property (nonatomic, strong) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize display;
#synthesize userIsInTheMiddleOfEnteringANumber;
#synthesize brain = _brain;
- (CalculatorBrain *)brain
{
if (!_brain) _brain = [[CalculatorBrain alloc] init];
return _brain;
}
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
if (self.userIsInTheMiddleOfEnteringANumber) {
self.display.text = [self.display.text stringByAppendingString:digit];
} else {
self.display.text = digit;
self.userIsInTheMiddleOfEnteringANumber = YES;
}
}
- (IBAction)enterPressed
{
[self.brain pushOperand:[self.display.text doubleValue]];
self.userIsInTheMiddleOfEnteringANumber = NO;
}
- (IBAction)operationPressed:(UIButton *)sender
{
if (self.userIsInTheMiddleOfEnteringANumber) [self enterPressed];
NSString *operation = [sender currentTitle];
double result = [self.brain performOperation:operation];
self.display.text = [NSString stringWithFormat:#"%g", result];
}
#end
According to https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/doc/uid/TP40006815-CH3-SW7
- (void)setTitle:(NSString *)title forState:(UIControlState)state
To set your button titles.
So in your case:
- (IBAction)operationPressed:(UIButton *)sender{
....
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateNormal];
// lets assume you want the down states as well:
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateSelected];
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateHighlighted];
}

Resources