Can't get setNeedsDisplay not working with my custom view to show changes - iphone

I'm trying to create a CGRect inside of a custom view (rectView) that will move up and down as you move a slider.
My slider's IBAction calls the following method: (which get's called fine)
- (void)moveRectUpOrDown:(int)y
{
self.verticalPositionOfRect += y;
[self setNeedsDisplay];
}
My drawRect method:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat size = 100;
self.rect = CGRectMake((self.bounds.size.width / 2) - (size / 2),
self.verticalPositionOfRect - (size / 2),
size,
size);
CGContextAddRect(context, self.rect);
CGContextFillPath(context);
}
My custom view's initWithFrame calls the drawRect method using setNeedsDisplay, but for some reason the moveRectUpOrDown won't call drawRect.
Any ideas what I'm doing wrong?
For clarity the entire implementation is below:
//ViewController.h
#import <UIKit/UIKit.h>
#import "rectView.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet rectView *rectView;
- (IBAction)sliderChanged:(id)sender;
#end
//ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize rectView;
- (void)viewDidLoad
{
[super viewDidLoad];
self.rectView = [[rectView alloc] initWithFrame:self.rectView.frame];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)sliderChanged:(id)sender
{
UISlider *slider = sender;
CGFloat sliderValue = slider.value;
[self.rectView moveRectUpOrDown:sliderValue];
}
#end
//rectView.h
#import <UIKit/UIKit.h>
#interface rectView : UIView
- (void)moveRectUpOrDown:(int)y;
#end
//rectView.m
#import "rectView.h"
#interface rectView ()
#property CGRect rect;
#property int verticalPositionOfRect;
#end
#implementation rectView
#synthesize rect, verticalPositionOfRect;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.verticalPositionOfRect = (self.bounds.size.height / 2);
[self setNeedsDisplay];
}
return self;
}
- (void)moveRectUpOrDown:(int)y
{
self.verticalPositionOfRect += y;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat size = 100.0;
self.rect = CGRectMake((self.bounds.size.width / 2) - (size / 2),
self.verticalPositionOfRect - (size / 2),
size,
size);
CGContextAddRect(context, self.rect);
CGContextFillPath(context);
}
#end
Thanks for the help :)

OK so the answer is the view is never actually added to the viewController's view..
You have an IBOutlet to your rectView - so I assume you dragged a UIView component onto the view in Interface Builder and then changed it's class to rectView, which is all fine BUT in viewDidLoad you wipe over this object with a new one
self.rectView = [[rectView alloc] initWithFrame:self.rectView.frame];
So this is now no longer the object that was loaded from the xib.
Subsequently this view is never actually added to the view hierarchy so it's never going to draw itself as it does not make sense.
So the solution is to remove the line I highlighted above.
Notes
I would probably still go with my other answer for such an implementation but it's helpful to get tripped up and learn new things.
rectView does not follow naming conventions. Ideally you should start your class name with a 2-3 letter prefix (possibly your initial's or company name) followed by a camel cased named.

I don't see how you initialize CGFloat size. Can you put a value in there and see how it works? The rest of the code looks okay to me.

An easier thing would be to just add a UIView and animate this around.
Add an ivar for this UIView
// .h
#property (nonatomic, strong) UIView *animatedView;
// .m
#synthesize animatedView = _animatedView;
then just replace your logic with this
- (void)moveRectUpOrDown:(int)y;
{
CGRect frame = self.animatedView.frame;
frame.origin.y += y;
// If you want the change to animate uncomment this
// [UIView animateWithDuration:0.25f
// animations:^{
// self.animatedView.frame = frame;
// }];
// If you don't want the change to animate uncomment this
// self.animatedView.frame = frame;
}

Related

Page controller not at change when page scroll

The Horizontal Scroll will work fine, but UIpagecontroller will not work means it will not change, As I scroll the page. I can't able to identify the error. Please see below code
#import "ViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIScrollView *scroll;
#property (strong, nonatomic) IBOutlet UIPageControl *pgcnt;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *arry=[NSArray arrayWithObjects:#"a",#"b",#"c",#"e",#"f", nil];
for (int i=0; i<arry.count; i++) {
CGRect frame;
[self.scroll setPagingEnabled:YES];
_scroll.pagingEnabled=YES;
_scroll.bounces = YES;
[_scroll setShowsHorizontalScrollIndicator:NO];
[_scroll setShowsVerticalScrollIndicator:NO];
frame.origin.x=_scroll.frame.size.width*i;
frame.size=_scroll.frame.size;
UIView *view=[[UIView alloc]initWithFrame:frame];
view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:[arry objectAtIndex:i]]];
[_scroll addSubview:view];
[self.pgcnt setCurrentPage:i];
// self.pgcnt.numberOfPages=arry.count;
}
_scroll.contentSize=CGSizeMake(_scroll.frame.size.width*arry.count,_scroll.frame.size.height);
// Do any additional setup after loading the view, typically from a nib.
}
Any suggestion or help will appreciated
I found the solution , no one helped me, but its ok, i will help other people .i Didn't added delegate method thats why the Pagecontrol dot will not worked. But now working fine.
pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scroll.frame.size.width;
int page = floor((self.scroll.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pgcnt.currentPage = page;
}
thanks for
http://iosmadesimple.blogspot.in/2013/01/page-control-for-switching-between-views.html

iPhone iOS 6 - Dismissing a subview crashes

I can't quite figure out what's going on but I have a view that displays a subview when a users selects a button. This subview then also has a button the user can select to cancel and remove this subview. When all of this happens, my app crashes when you attempt to close the subview.
This is my code:
From the main view that shows the subview when a button is selected -
-(IBAction)sendMessage:(id)sender{
NSLog(#"Going to send a message....");
CGRect frameBounds = [self.view bounds];
float frameWidth = frameBounds.size.width;
float frameHeight = frameBounds.size.height;
float frameX = frameBounds.origin.x;
//float frameY = frameBounds.size.height / 2;
float frameY = frameBounds.size.height;
float finalY = frameBounds.size.height / 1.75;
MessageChooserController *chooser = [[MessageChooserController alloc] initWithNibName:#"MessageChooser" bundle:nil];
//Set the frame off the screen at the bottom
chooser.view.frame = CGRectMake(frameX, frameY, frameWidth, frameHeight);
[self.view addSubview:chooser.view];
[UIView animateWithDuration:0.5 animations:^{chooser.view.frame = CGRectMake(frameX, finalY, frameWidth, frameHeight);}];
}
As you can see this simply shows a new subview - MessageChooserController. Now this subview, MessageChooserController has a button to cancel this "action".
The header file for MessageChooserController:
#import <UIKit/UIKit.h>
#interface MessageChooserController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *btn_sendEmail;
#property (weak, nonatomic) IBOutlet UIButton *btn_sendText;
#property (weak, nonatomic) IBOutlet UIButton *btn_cancel;
-(IBAction)closeChooser:(id)sender;
#end
And its implementation:
#import "MessageChooserController.h"
#interface MessageChooserController ()
#end
#implementation MessageChooserController
#synthesize btn_cancel, btn_sendEmail, btn_sendText;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
/*
[btn_cancel setBackgroundImage:[[UIImage imageNamed:#"iphone_delete_button.png"] stretchableImageWithLeftCapWidth:8.0f topCapHeight:0.0f] forState:UIControlStateNormal];
*/
/*
UIImage *cancelButtonImage = [[UIImage imageNamed:#"iphone_delete_button"] resizableImageWithCapInsets:UIEdgeInsetsMake(30,0,30,0)resizingMode:UIImageResizingModeStretch];
[btn_cancel setBackgroundImage:cancelButtonImage forState:UIControlStateNormal];
*/
}
-(IBAction)closeChooser:(id)sender{
[self.view removeFromSuperview];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
As you can see I have a simple method to close this subview, closeChooser. All of this compiles but when I select the cancel button on the subview my app crashes. I can't find anything anywhere about this.
Essentially I want to have a view display like it does when you select "Send message" from your contacts.
The correct way of doing this is calling [self presentModalViewController:viewController] on the parent view controller and then calling [self dismissModalViewController] when you want to hide it.

Call delegate method (iOS)

Fist of all I want to show you my code/storyboard:
This is my storyboard: I have a little UISlider and a UIView.
The UIView is a custom view and his class is "SquareView". This is the code:
SquareView.h
#import <UIKit/UIKit.h>
#class SquareView;
#protocol SquareViewDelegate <NSObject>
-(int)giveMeTheNumbersOfSquare:(SquareView *)squareView;
#end
#interface SquareView : UIView
#property (nonatomic , weak) IBOutlet id<SquareViewDelegate> delegate;
#end
and SquareView.m
#import "SquareView.h"
#implementation SquareView
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
int numberOfSquare = [delegate giveMeTheNumbersOfSquare:self];
NSLog(#"Value of numberOfSquare in drawRect---> %d" ,numberOfSquare);
//numberOfSquare = 20;
for (int i=0; i<numberOfSquare; i++) {
float x = arc4random() % (int)self.frame.size.width - 20;
float y = arc4random() % (int)self.frame.size.width - 20;
UIRectFill(CGRectMake(x, y, 20.0, 20.0));
// NSLog(#"X---> %f" ,x);
//NSLog(#"Y---> %f" ,y);
[self setNeedsDisplay];
}
// Drawing code
}
#end
Now the ViewController... The ViewController is the SquareView's Delegate.
ViewController.h
#import <UIKit/UIKit.h>
#import "SquareView.h"
#interface TestViewController : UIViewController <SquareViewDelegate>
#property (weak) IBOutlet SquareView *squareView;
#property(weak) IBOutlet UISlider *slider;
-(IBAction)changeSquareNumbers:(id)sender;
#end
and ViewController.m
#import "TestViewController.h"
#interface TestViewController ()
{
int _squareCount;
}
#end
#implementation TestViewController
#synthesize squareView = _squareView;
#synthesize slider = _slider;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)awakeFromNib
{
[_squareView setDelegate:self];
_squareCount = 50;
[self.squareView setNeedsDisplay];
}
/********* Delegate Method *********/
-(int)giveMeTheNumbersOfSquare:(SquareView *)squareView
{
//return _squareCount;
NSLog(#"Value of _squareCount in giveMeTheNumberOfSquare ---> %d" ,_squareCount);
return _squareCount;
}
-(IBAction)changeSquareNumbers:(UISlider *)sender
{
NSLog(#"Value of slider in changeSquareNumbers --> %f" ,[sender value]]);
_squareCount = (int)[sender value];
NSLog(#"Value of _sqareCount ---> %d" ,_squareCount);
[self.squareView setNeedsDisplay];
}
Now... in the SquareView.m file, in the drawRect function I don't know why the program NEVER call the "giveMetheNumbersOfSquare function. The "numberOfSquare" in drawRect stay at 0!!!
I don't understand why the program NEVER enter in the "giveMeTheNumberOfSquare" Function!!
Thanks!!
Make sure that the delegate is being set correctly. You might need to alloc or initialize your squareView. Also if you're using a storyboard you might not be calling awakeFromNib.

Text getting blur on zoom-in

I have requirement in which I have tableview as a subview of imageview. Now when the user zooms-in , the text inside the tableview is getting blur. Is there any way to manipulate it at time of zoom-in?
Please follow the steps which is below.
Don't set the position of image statically i mean by giving coordinate.Set the position dynamically or at the run time it will take position based on current window or zoom in zoom out position label,i am not pretty much sure because i havn't faced this situation earlier but as i think it might be use case scenario for solving your problem.
Thanks
I have achieved it by subclassing CALayer for labels. Thanks all for help.
Subclass label as follows :
TiledLable.h file ::
#import <UIKit/UIKit.h>
#import "FastCATiledLayer.h"
#interface TiledLable : UILabel
{
}
#end
TiledLale.m file ::
#import "TiledLable.h"
#import <QuartzCore/QuartzCore.h>
#implementation TiledLable
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code.
FastCATiledLayer *tiledLayer = (FastCATiledLayer *)[self layer];
tiledLayer.levelsOfDetail = 2;
tiledLayer.levelsOfDetailBias = 2;
tiledLayer.tileSize = CGSizeMake(1024.0,1024.0);
tiledLayer.contents = nil;
self.layer.contents = nil;
}
return self;
}
// Set the layer's class to be CATiledLayer.
+ (Class)layerClass
{
return [FastCATiledLayer class];
}
- (void)dealloc
{
((CATiledLayer *)[self layer]).delegate = nil;
[self removeFromSuperview];
[self.layer removeFromSuperlayer];
[super dealloc];
}
#end

Very Simple Custom UIView, drawRect not getting called

I have this super simple example, and I'm not sure why it is not working. drawRect Never gets called. I just want a square to draw and be red. What am I doing wrong?
//Controller.h
#import <Foundation/Foundation.h>
#class CustomView;
#interface Controller : NSObject
#property (nonatomic, retain) CustomView *cv;
#end
//Controller.m
#import "Controller.h"
#import "CustomView.h"
#implementation Controller
#synthesize cv;
- (void) awakeFromNib {
NSLog(#"awakeFromNib called");
CGRect theFrame = CGRectMake(20, 20, 100, 100);
cv = [[CustomView alloc] initWithFrame:theFrame];
UIWindow *theWindow = [[UIApplication sharedApplication] keyWindow];
[theWindow addSubview:cv];
[cv setNeedsDisplay];
}
#end
//CustomView.h
#import <UIKit/UIKit.h>
#interface CustomView : UIView
#end
//CustomView.m
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSLog(#"initWithFrame called");
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(#"drawRect called");
self.backgroundColor = [UIColor redColor];
}
#end
You aren't drawing anything in your drawRect. You are just setting a property on the view. If you have overridden drawRect, nothing will be drawn - try calling [super drawRect:rect] (after setting your background colour) or simply draw the square yourself using:
[[UIColor redColor] set];
[[UIBezierPath bezierPathWithRect:self.bounds] fill];
EDIT:
I see your drawRect is not even being called. I'm not sure of your nib structure, but try adding cv as a subview to self.view in your controller rather than adding it to the window. Also, note that you are not retaining cv (use self.cv = rather than cv =) but this shouldn't be an issue since your view will retain it.
Rather than doing a forward reference to your CustomView class in your Controller implementation:
#class CustomView;
Trying importing the class header file:
#import "CustomView.h"
Because you require access to the API you have defined when you call:
cv = [[CustomView alloc] initWithFrame:theFrame];
A forward reference tells the compiler that there will be an implementation for the class you are using at compile time and it is best used in header files. In implementation files, I find it best to import the header.