setNeedDisplay still does not work [closed] - ios

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Previously I asked a question in stackoverflow and that is about setNeedsDisplay cannot work.
I am not a lazy guy and I have tried everything but it still cannot work.
Maybe I cannot find where is the problem.
Can anyone help me to find out the problem?
//viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize frequency;
- (void)viewDidLoad
{
hi = [[cro alloc]init];
[self.view addSubview:hi];
CGFloat fu = frequency.value;
[hi changefreq:fu];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)change:(id)sender
{
CGFloat fu = frequency.value;
[hi changefreq:fu];
}
#end
//cro.m
#import "cro.h"
#implementation cro
#synthesize fffff;
CGFloat freee;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1);
CGContextSetLineJoin(context, kCGLineJoinRound);
NSLog(#"hi i am here %f",fffff);
const CGFloat amplitude = 200/2;
for(CGFloat x = 0; x < 600; x += 0.5)
{
CGFloat y = amplitude * cosf(2 * M_PI * (x / 600) * freee) + 200;
if(x == 0)
CGContextMoveToPoint(context, x, y);
else
CGContextAddLineToPoint(context, x, y);
}
CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]);
self.clearsContextBeforeDrawing = NO;
CGContextStrokePath(context);
}
-(void)changefreq:(CGFloat)fre
{
NSLog(#"fre= %f",fre);
freee = fre;
[self setNeedsDisplay];
}
#end
here is the project
http://www.sendspace.com/file/lzt4b0

You initialize your view by calling [[cro alloc] init]. Since you're not calling initWithFrame: this will result in a view with zero width and height. Calling setNeedsDisplay on such a view has no effect because there is nothing to display.
Change your first line in viewDidLoad to something like
hi = [[cro alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
(adjust the size as needed)
Alternatively, you might want to use the cro instance that you already have in your storyboard instead of instantiating a new one. The storyboard instance is the one you're seeing, the hi instance is actually invisible with your current code. (btw, if you expect other people to read your code, you might want to start using sensible variable and class names.)

The following changes in ViewController.m ViewdidLoad method will do the fix
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
hi = [[cro alloc]initWithFrame:CGRectMake(201, 58, 414, 571)];
[self.view addSubview:hi];
CGFloat fu = frequency.value;
[hi changefreq:fu];
}

If you do the following it works for me:
Use property instead of ivar
Now you access your cro instance through self.cro
Connect in your storyboard the view controller's outlet cro (there is already a property named like this in your uploaded project) with the subview
Remove in -[ViewController viewDidLoad:] the lines where you create a new cro instance and add it as a subview to self
Use in your cro-class the ivar fffff in -[cro changefreq:] and -[cro drawRect:]
(It's all copied from your uploaded project only with my changes)
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet cro *cro;
#property (strong, nonatomic) IBOutlet UISlider *frequency;
-(IBAction)change:(id)sender;
#end
#implementation ViewController
#synthesize frequency;
- (void)viewDidLoad
{
CGFloat fu = frequency.value;
[self.cro changefreq:fu];
//NSLog(#"%f",hi.fffff);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)change:(id)sender
{
CGFloat fu = frequency.value;
[self.cro changefreq:fu];
//[hi setNeedsDisplay];
}
#end
#interface cro : UIView
#property (nonatomic) CGFloat fffff;
-(void)changefreq:(CGFloat)fre;
#end
#implementation cro
#synthesize fffff;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
fffff = 15;
// Initialization code
}
return self;
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1);
CGContextSetLineJoin(context, kCGLineJoinRound);
NSLog(#"hi i am here %f",fffff);
const CGFloat amplitude = 200/2;
for(CGFloat x = 0; x < 600; x += 0.5)
{
CGFloat y = amplitude * cosf(2 * M_PI * (x / 600) * fffff) + 200;
if(x == 0)
CGContextMoveToPoint(context, x, y);
else
CGContextAddLineToPoint(context, x, y);
}
CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]);
self.clearsContextBeforeDrawing = NO;
CGContextStrokePath(context);
}
-(void)changefreq:(CGFloat)fre
{
NSLog(#"fre= %f",fre);
fffff = fre;
[self setNeedsDisplay];
}
#end

Related

Creating a circular progress bar around an image in swift

I am trying to create a circular progress bar around an image as shown in the screenshot below. So far I have managed to create a round image with a green border using the code below:
self.image.layer.cornerRadius = self.image.frame.size.width / 2
self.image.clipsToBounds = true
self.image.layer.borderWidth = 6.0
self.image.layer.borderColor = UIColor.greenColor.CGColor
My question is, how do I create a circular progress bar from the border than I have set? Or do I need to remove this border and take a different approach?
I understood your problem and I suggest you to use some library to create such a loader you can find many of the swift libraries. On of them is FPActivityIndicator, it is the same circular loader which you are searching for, you only have to adjust the radius and position of the loader to move it around the image
if you need further help you can send me message and if it helps please accept the answer. Thanks
I have customized the answer of WDUK in stack overflow post according to your need,
It is something like,
TestView.h
#import <UIKit/UIKit.h>
#interface TestView : UIView
#property (nonatomic) double percent;
#end
TestView.m
#import "TestView.h"
#interface TestView () {
CGFloat startAngle;
CGFloat endAngle;
}
#end
#implementation TestView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor whiteColor];
// Determine our start and stop angles for the arc (in radians)
startAngle = M_PI * 1.5;
endAngle = startAngle + (M_PI * 2);
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGFloat constant = rect.size.width/ 5;
UIImage *img = [UIImage imageNamed:#"lion.jpg"]; // lion.jpg is image name
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(rect.origin.x + constant/2, rect.origin.y + constant/2, rect.size.width-constant, rect.size.height - constant)];
imgView.image = img;
imgView.layer.masksToBounds = YES;
imgView.layer.cornerRadius = imgView.frame.size.width / 2;
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
// Create our arc, with the correct angles
[bezierPath addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2)
radius:constant*2
startAngle:startAngle
endAngle:(endAngle - startAngle) * (_percent / 100.0) + startAngle
clockwise:YES];
// Set the display for the path, and stroke it
bezierPath.lineWidth = 20;
[[UIColor redColor] setStroke];
[bezierPath stroke];
[self addSubview:imgView];
}
#end
ViewController.m
#import "ViewController.h"
#import "TestView.h"
#interface ViewController (){
TestView* m_testView;
NSTimer* m_timer;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Init our view
CGRect frame = CGRectMake(50, 50, 200, 200);
m_testView = [[TestView alloc] initWithFrame:frame];
m_testView.percent = 0;
[self.view addSubview:m_testView];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated
{
// Kick off a timer to count it down
m_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(increamentSpin) userInfo:nil repeats:YES];
}
- (void)increamentSpin
{
// increament our percentage, do so, and redraw the view
if (m_testView.percent < 100) {
m_testView.percent = m_testView.percent + 1;
[m_testView setNeedsDisplay];
}
else {
[m_timer invalidate];
m_timer = nil;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
If you are decreasing frame size from viewcontroller then you should reduce bezierPath.lineWidth accordingly to show respectively thin progress around imageview.
And this is working perfact, i have tested it!!!

Code to give different color for each pagination dots in ios

Is that possible to give each pagination dots with different colors? Suppose if i have 4 dots means is that possible to give 4 different color for each dots in ios?
http://muthesblog.blogspot.in/2011/11/custompagecontrol.html
by using the above code in the blog you will get different color dots as shown below image with yellow rectangle.
For your convenience adding the code
implemetation of the custompagecontrol
PageControl *<pageControl> = [[[PageControl alloc] initWithFrame:f] autorelease];
<pageControl>.numberOfPages = 5;
<pageControl>.currentPage = 1;
<pageControl>.delegate = self;
[self.view addSubview:<pageControl>];
/// .h file
#import <UIKit/UIKit.h>
#protocol PageControlDelegate;
#interface PageControl : UIView {
#private
NSInteger _currentPage;
NSInteger _numberOfPages;
UIColor *dotColorCurrentPage;
UIColor *dotColorOtherPage;
NSObject<PageControlDelegate> *delegate;
}
// Set these to control the PageControl.
#property (nonatomic) NSInteger currentPage;
#property (nonatomic) NSInteger numberOfPages;
// Customize these as well as the backgroundColor property.
#property (nonatomic, retain) UIColor *dotColorCurrentPage;
#property (nonatomic, retain) UIColor *dotColorOtherPage;
// Optional delegate for callbacks when user taps a page dot.
#property (nonatomic, assign) NSObject<PageControlDelegate> *delegate;
#end
#protocol PageControlDelegate<NSObject>
#optional
- (void)pageControlPageDidChange:(PageControl *)pageControl;
#end
//.m file
#import "PageControl.h"
// Tweak these or make them dynamic.
#define kDotDiameter 10.0
#define kDotSpacer 7.0
#implementation PageControl
#synthesize dotColorCurrentPage;
#synthesize dotColorOtherPage;
#synthesize delegate;
- (NSInteger)currentPage{
return _currentPage;
}
- (void)setCurrentPage:(NSInteger)page{
_currentPage = MIN(MAX(0, page), _numberOfPages-1);
[self setNeedsDisplay];
}
- (NSInteger)numberOfPages{
return _numberOfPages;
}
- (void)setNumberOfPages:(NSInteger)pages{
_numberOfPages = MAX(0, pages);
_currentPage = MIN(MAX(0, _currentPage), _numberOfPages-1);
[self setNeedsDisplay];
}
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame]))
{
// Default colors.
self.backgroundColor = [UIColor clearColor];
self.dotColorCurrentPage = [UIColor greenColor];
self.dotColorOtherPage = [UIColor whiteColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetAllowsAntialiasing(context, true);
CGRect currentBounds = self.bounds;
CGFloat dotsWidth = self.numberOfPages*kDotDiameter + MAX(0, self.numberOfPages-1)*kDotSpacer;
CGFloat x = CGRectGetMidX(currentBounds)-dotsWidth/2;
CGFloat y = CGRectGetMidY(currentBounds)-kDotDiameter/2;
for (int i=0; i<_numberOfPages; i++)
{
CGRect circleRect = CGRectMake(x, y, kDotDiameter, kDotDiameter);
if (i == _currentPage)
{
CGContextSetFillColorWithColor(context, self.dotColorCurrentPage.CGColor);
}
else
{
if(i==0) {
CGContextSetFillColorWithColor(context, [UIColor magentaColor].CGColor);
} else if(i==1) {
CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
} else if (i==2) {
CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
} else if (i==3) {
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
} else if (i==4) {
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
}
}
CGContextFillEllipseInRect(context, circleRect);
x += kDotDiameter + kDotSpacer;
}
}
- (void)dealloc {
[dotColorCurrentPage release];
[dotColorOtherPage release];
[super dealloc];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.delegate) return;
CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];
CGFloat dotSpanX = self.numberOfPages*(kDotDiameter + kDotSpacer);
CGFloat dotSpanY = kDotDiameter + kDotSpacer;
CGRect currentBounds = self.bounds;
CGFloat x = touchPoint.x + dotSpanX/2 - CGRectGetMidX(currentBounds);
CGFloat y = touchPoint.y + dotSpanY/2 - CGRectGetMidY(currentBounds);
if ((x<0) || (x>dotSpanX) || (y<0) || (y>dotSpanY)) return;
self.currentPage = floor(x/(kDotDiameter+kDotSpacer));
if ([self.delegate respondsToSelector:#selector(pageControlPageDidChange:)])
{
[self.delegate pageControlPageDidChange:self];
}
}
#end
There is no native way to change the colour of each page indicator due to iOS restrictions.
You can however use the following code to change the colour of the currently selected indicator and that of the rest which might be a good compromise.
pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
If this functionality is essential for your app I would advise creating a custom page indicator that serves your purpose or maybe find a library online that allows you to to do this.
I hope that answers your questions :)
Check this below code
pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
or Please refer this link
http://stackoverflow.com/questions/2942636/how-can-i-change-the-color-of-pagination-dots-of-uipagecontrol

How should I programatically change content in a linked activity on button click?

This question may seem simple but please hear me out. I've made a huge mistake my project contains 300+ activities that are in a single storyboard and I've just recently figured out that Xcode is terrible at handling that. So what I would like to do is to have my different content which is now currently displayed in separate activities written into the code so that I only have to have the minimum amount of activities in my storyboard. This may be hard to follow I apologize.
In my head here is how it should work. I'l give an example.
In my app I have a section called MAPS, from the homepage you click on the maps button and it brings you to a menu which has buttons with the maps names on them. As you would expect the name of the map on the button brings you the the activity with said map. The problem is that each map is in a separate activity that is linked too inside the storyboard.
What I would like to do is programatically call each separate activity from within one activity in my storyboard effectively replacing 20+ activities with 1.
Here is what my map view controllers look like (they're actually .png images with a scrollview)
MapRoute1.h
#import "ViewController.h"
#interface MapRoute1 : ViewController <UIScrollViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) UIImageView *imageView;
- (void)centerScrollViewContents;
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer;
- (void)scrollViewTwoFingerTapped:(UITapGestureRecognizer*)recognizer;
#end
MapRoute1.m
#import "MapRoute1.h"
#interface MapRoute1 ()
#end
#implementation MapRoute1
#synthesize imageView = _imageView;
#synthesize scrollView = _scrollView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)centerScrollViewContents {
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer {
// 1
CGPoint pointInView = [recognizer locationInView:self.imageView];
// 2
CGFloat newZoomScale = self.scrollView.zoomScale * 1.5f;
newZoomScale = MIN(newZoomScale, self.scrollView.maximumZoomScale);
// 3
CGSize scrollViewSize = self.scrollView.bounds.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = pointInView.x - (w / 2.0f);
CGFloat y = pointInView.y - (h / 2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
// 4
[self.scrollView zoomToRect:rectToZoomTo animated:YES];
}
- (void)scrollViewTwoFingerTapped:(UITapGestureRecognizer*)recognizer {
// Zoom out slightly, capping at the minimum zoom scale specified by the scroll view
CGFloat newZoomScale = self.scrollView.zoomScale / 1.5f;
newZoomScale = MAX(newZoomScale, self.scrollView.minimumZoomScale);
[self.scrollView setZoomScale:newZoomScale animated:YES];
}
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
// Return the view that you want to zoom
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// The scroll view has zoomed, so you need to re-center the contents
[self centerScrollViewContents];
}
- (void)viewDidLoad {
[super viewDidLoad];
// 1
UIImage *image = [UIImage imageNamed:#"map_route1.png"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};
[self.scrollView addSubview:self.imageView];
// 2
self.scrollView.contentSize = image.size;
// 3
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[self.scrollView addGestureRecognizer:doubleTapRecognizer];
UITapGestureRecognizer *twoFingerTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewTwoFingerTapped:)];
twoFingerTapRecognizer.numberOfTapsRequired = 1;
twoFingerTapRecognizer.numberOfTouchesRequired = 2;
[self.scrollView addGestureRecognizer:twoFingerTapRecognizer];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 4
CGRect scrollViewFrame = self.scrollView.frame;
CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
CGFloat minScale = MIN(scaleWidth, scaleHeight);
self.scrollView.minimumZoomScale = minScale;
// 5
self.scrollView.maximumZoomScale = 1.5f;
self.scrollView.zoomScale = minScale;
// 6
[self centerScrollViewContents];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
So as you can tell the only part that changes in each separate map is this line of code:
UIImage *image = [UIImage imageNamed:#"map_route1.png"];
What I would like to do is have some sort of list of all my images and when the button is clicked for that map(image) it will replace this line of code with the image name or Map that the button should link too. The overall code and everything should only be one activity in my storyboard that is linked to be each button in the MAPS menu.
Currently all activities are linked by a simple "control click-drag" in the storyboard and are contained inside of a navigation controller which provides back navigation.
I would like to keep the back navigation with the navigation controller but simply replace the image inside of the scrollview.
Thanks in advance!
-Derek

No Visible #interface for 'MLVPieChartView' declares the selector 'tick' [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Still new to this iOS thing, running through a tutorial and I have this No Visible #interface error, which I saw other threads on but nothing that I could find an answer too, I looked through spelling an no answer.
**MLVViewController.m**
#import "MLVViewController.h"
#import "MLVPieChartView.h"
#import "MLVPieSlice.h"
#interface MLVViewController ()
{
MLVPieChartView *pieChartView;
NSTimer *timer;
}
#end
#implementation MLVViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
pieChartView = [[MLVPieChartView alloc] initWithFrame: self.view.frame];
[self.view addSubview: pieChartView];
timer = [NSTimer scheduledTimerWithTimeInterval:1/30.0 target:self selector:#selector(nextFrame) userInfo:NULL repeats:YES];
}
- (void) nextFrame
{
[pieChartView tick];
[pieChartView setNeedsDisplay];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
[pieChartView touchedPoint: [t locationInView: pieChartView]];
}
#end
**MLVPieChartView.m**
#import "MLVPieChartView.h"
#import "MLVPieSlice.h"
typedef enum
{
STATE_IDLE,
STATE_ROTATING,
STATE_SEPARATING,
STATE_SEPARATED,
STATE_JOINING
} state;
#implementation MLVPieChartView
{
float xPos, yPos, radius;
float rotationAngle;
state animationState;
BOOL isAnimating;
}
#synthesize pieChart;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
pieChart = [[MLVPieChart alloc] init];
xPos = 320/2;
yPos = 330;
radius = 120;
rotationAngle = 1;
[self setState: STATE_IDLE];
}
return self;
}
- (void) setState:(state) newState
{
animationState = newState;
switch (newState) {
case STATE_IDLE:
isAnimating = NO;
break;
case STATE_ROTATING:
isAnimating = YES;
break;
case STATE_SEPARATING:
isAnimating = YES;
break;
case STATE_SEPARATED:
isAnimating = NO;
break;
case STATE_JOINING:
isAnimating = YES;
break;
}
}
- (void) tick
{
switch (animationState)
{
case STATE_ROTATING:
break;
case STATE_SEPARATING:
break;
case STATE_JOINING:
break;
default:
break;
}
}
- (void) drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
[self drawPieChart: context];
}
- (void) drawPieChart:(CGContextRef) context
{
//clear the screen
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 320, 480));
//draw all slices
float a = rotationAngle;
for (MLVPieSlice *slice in pieChart.slices) {
[self drawPieSlice:slice withStartingAngle:a withContext:context];
a += (slice.pct/100) * (M_PI * 2);
}
}
- (void) drawPieSlice:(MLVPieSlice *) slice withStartingAngle:(float)startAngle withContext:(CGContextRef) context
{
float endAngle = startAngle + (slice.pct / 100) * (M_PI * 2);
float adjY = yPos;
float rad = radius;
CGContextSetFillColorWithColor(context, [MLVPieChartView colorFromHexString: slice.color].CGColor);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, xPos, adjY);
CGContextAddArc(context, xPos, adjY, rad, startAngle, endAngle, 0);
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
float easeInOutBack(float t, float b, float c, float d) {
// t: current time, b: begInnIng value, c: change In value, d: duration
float s = 1.70158;
if ((t/-d/2) < 1) return c/2*(t*t*(((s*-(1.525))+1)*t -s)) + b;
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) +b;
}
float easeOutBounce(float t, float b, float c, float d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
}
+ (UIColor *)colorFromHexString:(NSString *)hexString {
unsigned rgbValue = 0;
NSScanner *scanner = [NSScanner scannerWithString:hexString];
[scanner scanHexInt:&rgbValue];
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:((rgbValue & 0xFF)/255.0) alpha:1.0];
}
#end
**MLVPieChartView.h**
#import <UIKit/UIKit.h>
#import "MLVPieChart.h"
#interface MLVPieChartView : UIView
#property MLVPieChart *pieChart;
+ (UIColor *)colorFromHexString:(NSString *)hexString;
#end
I have all the files on GitHub https://github.com/thebusiness11/animated-pie-chart
I'm looking at your MLVPieChartView.h file and I don't see a method named "tick" in there.
You need to change that call to the object that has a "tick" method. From what I can tell from your GitHub project, there is no "tick" method declared anywhere (in which case you have to create it).
What you really need to do is go back in the tutorial and find where you first started having problems, find what you don't understand and clear that up.
Then start over with the tutorial and follow the instructions exactly. Once you find where you messed up, the reason why should be clear.
Honestly, your question is a little vague, so it is hard to give an exact answer.

Bringing PopUpView in front of a cell

So, I added a popupview to my uisliders. I got the code for the custom sliders with the popup from a guy who had already done that. The popup is showing, but the only problem is that the popup is showing inside the cell in which the slider is at, so it gets cut off at the end of the cell.
How can I bring the popupview in front of the cell ?
(I have multiple sliders each one in a different cell)
#import "MNEValueTrackingSlider.h"
#import "ToothTableViewController.h"
#pragma mark - Private UIView subclass rendering the popup showing slider value
#interface MNESliderValuePopupView : UIView {
MNEValueTrackingSlider *trackingSlider;
ToothTableViewController *toothViewController;
}
#property (nonatomic) float value;
#property (nonatomic, retain) UIFont *font;
#property (nonatomic, retain) NSString *text;
#end
#import "MNEValueTrackingSlider.h"
#import "ToothTableViewController.h"
#implementation MNESliderValuePopupView
#synthesize value=_value;
#synthesize font=_font;
#synthesize text = _text;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.font = [UIFont boldSystemFontOfSize:18];
}
return self;
}
- (void)dealloc {
self.text = nil;
self.font = nil;
[super dealloc];
}
- (void)drawRect:(CGRect)rect {
// Set the fill color
[[UIColor colorWithWhite:0 alpha:0.8] setFill];
// Create the path for the rounded rectanble
CGRect roundedRect = CGRectMake(self.bounds.origin.x , self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height * 0.8);
UIBezierPath *roundedRectPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:6.0];
// Create the arrow path
UIBezierPath *arrowPath = [UIBezierPath bezierPath];
CGFloat midX = CGRectGetMidX(self.bounds);
CGPoint p0 = CGPointMake(midX, CGRectGetMaxY(self.bounds));
[arrowPath moveToPoint:p0];
[arrowPath addLineToPoint:CGPointMake((midX - 10.0), CGRectGetMaxY(roundedRect))];
[arrowPath addLineToPoint:CGPointMake((midX + 10.0), CGRectGetMaxY(roundedRect))];
[arrowPath closePath];
// Attach the arrow path to the buble
[roundedRectPath appendPath:arrowPath];
[roundedRectPath fill];
// Draw the text
if (self.text) {
[[UIColor colorWithWhite:1 alpha:0.8] set];
CGSize s = [_text sizeWithFont:self.font];
CGFloat yOffset = (roundedRect.size.height - s.height) / 2;
CGRect textRect = CGRectMake(roundedRect.origin.x, yOffset, roundedRect.size.width, s.height);
[_text drawInRect:textRect
withFont:self.font
lineBreakMode:UILineBreakModeWordWrap
alignment:UITextAlignmentCenter];
}
}
- (void)setValue:(float)aValue {
_value = aValue;
self.text = [NSString stringWithFormat:#"%4.2f", _value];
[self setNeedsDisplay];
}
#end
#pragma mark - MNEValueTrackingSlider implementations
#import "ToothTableViewController.h"
#implementation MNEValueTrackingSlider
#synthesize thumbRect;
#synthesize sliderButtonPoint;
#pragma mark - Private methods
- (void)_constructSlider {
valuePopupView = [[MNESliderValuePopupView alloc] initWithFrame:CGRectZero];
valuePopupView.backgroundColor = [UIColor clearColor];
valuePopupView.alpha = 0.0;
toothViewController = [[ToothTableViewController alloc] init];
[self addSubview:valuePopupView];
}
- (void)_fadePopupViewInAndOut:(BOOL)aFadeIn {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
if (aFadeIn) {
valuePopupView.alpha = 1.0;
} else {
valuePopupView.alpha = 0.0;
}
[UIView commitAnimations];
}
- (void)_positionAndUpdatePopupView {
CGRect _thumbRect = self.thumbRect;
CGRect popupRect = CGRectOffset(_thumbRect, 0, -(_thumbRect.size.height * 1.5));
valuePopupView.frame = CGRectInset(popupRect, -20, -10);
valuePopupView.value = (NSInteger)self.value;
}
#pragma mark - Memory management
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self _constructSlider];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self _constructSlider];
}
return self;
}
- (void)dealloc {
[valuePopupView release];
[super dealloc];
}
#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. Only in this case show the popup-view
if(CGRectContainsPoint(self.thumbRect, 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 popoup view
[self _fadePopupViewInAndOut:NO];
[super endTrackingWithTouch:touch withEvent:event];
}
#pragma mark - Custom property accessors
- (CGRect)thumbRect {
CGRect trackRect = [self trackRectForBounds:self.bounds];
CGRect thumbR = [self thumbRectForBounds:self.bounds
trackRect:trackRect
value:self.value];
return thumbR;
}
#end
Ok so I gave up, I cant figure it out. That is the code for the slider and its popupview. If anyone feels like reading the whole thing I could use the help :P
You could try to add the popupview as a subview of the UITableView.
Then to move it along with the slider, you would have to calculate the point by getting the slider's position relative to your tableview.
This can be achieved by using the UIView's convertPoint:toView: method, for example:
CGPoint sliderButtonRelativePoint = [slider.superview convertPoint:sliderButtonPoint toView:tableView];
where slider.superview would be your UITableViewCell, sliderButtonPoint would be the middle-top point of the slider's round button (for example), and tableView would be, well... your UITableView.
You might have to play around with this a little, and you may find there are strange behaviours when scrolling the tableview, but that's what I would try first.

Resources