I create a category of UIButton class, use IB_DESIGNABLE. But I got an strange error Failed to render instance of RoundedCornerButton: Rendering the view took longer than 200 ms. Your drawing code may suffer from slow performance. I tried many suggestions on this website but still cannot fix it. please help me to find the root cause.Please see the image for more detail (RoundedCornerButton: is the category of UIButton class)
Update: the code for RoundedCornerButton class:
.h file
#import <UIKit/UIKit.h>
IB_DESIGNABLE
#interface RoundedCornerButton : UIButton
#property (nonatomic) IBInspectable int cornerRadius;
#property (nonatomic) IBInspectable int borderWidth;
#property (nonatomic) IBInspectable UIColor* borderColor;
#end
.m file:
#import "RoundedCornerButton.h"
#implementation RoundedCornerButton
-(void)drawRect:(CGRect)rect{
self.layer.borderWidth = self.borderWidth;
self.layer.borderColor = self.borderColor.CGColor;
[self.layer setCornerRadius:self.cornerRadius];
self.clipsToBounds = YES;
}
#end
I can run my project on device successful, but I got the Red warning as above.(It so strange, I use Xcode 7.0)
You mustn't play with your layer in drawRect like that. That isn't drawing! Drawing is about content.
Move that code somewhere else, such as awakeFromNib and prepareForInterfaceBuilder (both), and all will be well.
Here's example code:
#implementation RoundedCornerButton
-(void) config {
self.layer.borderWidth = self.borderWidth;
self.layer.borderColor = self.borderColor.CGColor;
[self.layer setCornerRadius:self.cornerRadius];
self.clipsToBounds = YES;
}
-(void)prepareForInterfaceBuilder {
[self config];
}
-(void)awakeFromNib {
[super awakeFromNib];
[self config];
}
#end
And you can see it works fine in IB in Xcode 7:
Related
A function circleOfButtons:buttonSize:radius: in SGView (below) is called from ParentView and I want ParentView to define the values inside SGView whenever ParentView sends a message to SGView.
This is the implementation file.
#import <UIKit/UIKit.h>
#import “ParentView.h"
#import "SGView.h"
#implementation ParentView : UIView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:[UIScreen mainScreen].bounds];
if (self) {
self.backgroundColor = [UIColor lightGrayColor];
int count = 5;
CGFloat size = 80.0;
CGFloat radius = 68;
SGView *myView = [SGView circleOfButtons:count buttonSize:size radius:radius];
[self addSubview:myView];
}
return self;
}
SGView arranges multiple UIButtons in a circle and is essentially like this
#import "SGView.h"
#implementation SGView : UIView
+(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius
{
UIView *multipleViews = [self new];
// … circular geometry …
[multipleViews addSubview:circleButton];
}
return multipleViews;
}
#end
The error message - at the line SGView *myView - is:
No known class method for selector
'circleOfButtons:buttonSize:radius:'
My guess is the compiler wants a declaration in the interface. I’m working through these tutorials trying to decide what the interface file should look like and though there are 6 SO questions that may already have answered my question, only this one had an example that seemed vaguely relevant.
This is my interface file.
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "SGView.h"
#interface ParentView : UIView {
}
+(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius;
#end
Can anyone please give an example showing what this interface file should look like ? Thanks.
UPDATE
Here is SGView.h (revised)
#import <UIKit/UIKit.h>
#interface SGView : UIView {
}
+(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius;
#end
I also noticed if the statement
SGView *myView = [SGView circleOfButtons:count buttonSize:size radius:radius];
is changed to
SGView *myView = [self circleOfButtons:count buttonSize:size radius:radius];
the error changes to
No visible #interface for 'ParentView' declares the selector 'circleOfButtons:buttonSize:radius:'
it was previously
No known class method for selector 'circleOfButtons:buttonSize:radius:'
You are calling
SGView *myView = [SGView circleOfButtons:count buttonSize:size radius:radius];
It should be
SGView *myView = [SGView circleOfButtons:count buttonSize:size circleRadius:radius];
Declare +(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius in SGView.h file.
Now you will get the method in ParentView class.
Happy coding :) .
I have created a custom UIView (ProgressView) where I draw a shape imported via StyleKit from PaintCode.
Below are the codes. I have declared instance variable property in my custom UIView and when I try to change property from ViewController, It does not work.
ProgressView.h
#import <UIKit/UIKit.h>
#interface ProogressView : UIView
#property (nonatomic) float daysFraction;
#property (nonatomic) float pagesFraction;
#end
ProgressView.m
#import "ProgressView.h"
#import "StyleKitName.h"
#import "ViewController.h"
#implementation ProgressView
#synthesize daysFraction = _daysFraction;
#synthesize pagesFraction = _pagesFraction;
- (void)drawRect:(CGRect)rect {
// Drawing code
[StyleKitName drawCanvas1WithDaysFraction:self.daysFraction pageFraction:self.pagesFraction];
}
-(void)awakeFromNib {
[super awakeFromNib];
self.pagesFraction = 0;
self.daysFraction = 0;
}
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
*ViewController.m**
#import "ViewController.h"
#import "ButtonAnimation.h"
#import "ProgressView.h"
#import "StyleKitName.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet ButtonAnimation *buttonView;
#property (weak, nonatomic) IBOutlet UIButton *actionButton;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ProgressView *new =[[ ProgressView alloc]init];
new.daysFraction = 0.7f; // here I am setting value to variable in custom view ProgressView but not working.
}
- (IBAction)animateTheButton:(id)sender {
self.buttonView.layer.backgroundColor = [UIColor clearColor].CGColor;
[self.buttonView addErrorAnimation];
}
#end
You need to add this view to UIViewController's view:
[self.view addSubview:progressView];
Later, you must also set a frame. Eg
[progressView setFrame:self.view.bounds];
You may do it in viewDid/WillLayoutSubviews method to change it on rotation / window resize event.
BTW, do not name your view as new, it's horrible. Such name doesn't even tell what kind of variable is it.
I created a CommonMethod subclass of NSObject for customizing UINavigationBar here is the CommonMethod.h and CommonMethod.m files
CommonMethod.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface CommonMethods : NSObject
+(void)setNavBackButton:(id)viewController;
+(void)setNavBackground:(id)viewController Color:(UIColor *)color;
#end
CommonMethod.h
#import <UIKit/UIKit.h>
#import "CommonMethods.h"
#implementation CommonMethods
+(void)setNavBackground:(id)viewController Color:(UIColor *)color
{
UIViewController *controller = (id)viewController;
controller.navigationController.navigationBar.backgroundColor=[UIColor redColor];
}
#end
Now when I am calling [CommonMethods setNavBackground:self Color:[UIColor redColor]; it is executing the method but didn't change anything on UI. Can anyone expalin this what I am missing ?
Edit :
I also tried controller.navigationController.navigationBar.barTintColor = color;
You have minor Mistake on Code
+(void)setNavBackground:(id)viewController Color:(UIColor *)color
{
UIViewController *controller = (id)viewController;
controller.navigationController.navigationBar.barTintColor = color; // Change NavigationBar color to Red
}
Call Method like this:[CommonMethod setNavBackground:self Color:[UIColor redColor]];
I'm not sure if I have my view controller in my storyboard file connected to my view correctly but here's a breakdown of the setup - I'm using xcode 5:
One view controller using custom class CICBoostGaugeViewController (configured in identity inspector).
One view using custom class CICGaugeBuilder (configured in identity inspector in storyboard file).
The CICGaugeBuilder class draws a gauge and sets the properties of the gauge in an init method. When I run this setup in the simulator the gauge appears correctly based on the initialized gauge parameters in CICGaugeBuilder. No problems so far.
My issue is when I create an instance of the CICGaugeBuilder class in my view controller and set the properties, they do not show up when I run it in the sim, only the values initialized in the CICGaugeBuilder class are applied.
CICBoostGaugeViewController.h
#import <UIKit/UIKit.h>
#import "CICGaugeBuilder.h"
#class CICGaugeBuilder;
#interface CICBoostGaugeViewController : UIViewController{
CICGaugeBuilder *boostGauge;
}
#property (nonatomic, retain) IBOutlet CICGaugeBuilder *boostGauge;
#end
CICBoostGaugeViewController.m
#import "CICBoostGaugeViewController.h"
#import "CICGaugeBuilder.h"
#interface CICBoostGaugeViewController ()
#end
#implementation CICBoostGaugeViewController
#synthesize boostGauge;
- (void)viewDidLoad
{
[super viewDidLoad];
self.boostGauge.minGaugeNumber = 0;
self.boostGauge.maxGaugeNumber = 25;
self.boostGauge.gaugeLabel = #"Boost/Vac";
self.boostGauge.incrementPerLargeTick = 10;
self.boostGauge.tickStartAngleDegrees = 135;
self.boostGauge.tickDistance = 270;
self.boostGauge.menuItemsFont = [UIFont fontWithName:#"Helvetica" size:14];
self.boostGauge.value = 10;
}
- (void)viewDidUnload
{
//self.boostGauge = nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This is the initialization method in the CICGaugeBuilder class:
self.minGaugeNumber = 0;
self.maxGaugeNumber = 100;
self.gaugeType = 2;
self.gaugeLabel = #"Boost/Vac";
self.incrementPerLargeTick = 10;
self.tickStartAngleDegrees = 135;
self.tickDistance = 270;
self.menuItemsFont = [UIFont fontWithName:#"Helvetica" size:14];
Note that the maxGaugeNumber of 100 is retained when run in the simulator. The gauge draws correctly, but the problem is the object instance in the view controller is not used. I've tried [self.boostGauge SetNeedsDisplay] and it did not work.
In my storyboard file the view controller does not have any referencing outlets. I think this needs to be connected to the app delegate but I'm not sure. Dragging the view controller to the app delegate does not allow a connection to be made.
Here is the CICAppDelegate.h file:
#import <UIKit/UIKit.h>
#class CICBoostGaugeViewController;
#interface CICAppDelegate : UIResponder <UIApplicationDelegate>{
UIWindow *window;
CICBoostGaugeViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet CICBoostGaugeViewController *viewController;
#end
As I go through you App,I found.
After calling [self.boostGauge SetNeedsDisplay] will not make any kind of effect because:
SetNeedsDisplay calls the - (void)drawRect:(CGRect)rect method of CICGaugeBuilder Class
and
- (void)drawRect:(CGRect)rect
{
CGRect innerFrame;
// self.value = 0;
[self initializeGauge];
}
here you again calling initialize method and initialise method will again set value to initial value.
ULTIMATELY NO EFFECT.
Most importantly you call value using
CICAppDelegate *ap=(CICAppDelegate *)[[UIApplication sharedApplication]delegate];
ap.guage.value=50;
Take a object reference of CICGaugeBuilder Class in appDel.
Add following to initialiseGuageMethod
CICAppDelegate *ap=(CICAppDelegate *)[[UIApplication sharedApplication]delegate];
ap.guage=self;
I am trying to changing the visual aspects of my button, however I am trying to use the FlatUIKit's button aspect, for those who don't know what that is that ok as it doesn't matter, in the example project that they provide they change the color of an IBOutlet button however it dosen't work the same with an IBAction heres their example code:
#import "ViewController.h"
#import "FUIButton.h"
#import "UIColor+FlatUI.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet FUIButton *alertViewButton;
//as you can see its a FUIButton, and I'm not sure how to use that with an IBAction
#end
#implementation ViewController
- (void)viewDidLoad
{
self.alertViewButton.buttonColor = [UIColor peterRiverColor];
self.alertViewButton.shadowColor = [UIColor silverColor];
self.alertViewButton.shadowHeight = 3.0f;
self.alertViewButton.cornerRadius = 6.0f;
self.alertViewButton.titleLabel.font = [UIFont boldFlatFontOfSize:16];
[self.alertViewButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal];
[self.alertViewButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateHighlighted];
}
Heres my code this far:
my .h
#import <UIKit/UIKit.h>
#interface HomeViewController : UIViewController {
}
- (IBAction)start:(id)sender;
#end
my .m:
#import "HomeViewController.h"
#import "UIColor+FlatUI.h"
#import "FUIButton.h"
#interface HomeViewController ()
#end
#implementation HomeViewController
- (IBAction)start:(id)sender {
//this is the button i want change the appearance of.
}
I am stuck with this, the button I want to use the FUIButton color effects is the IBAction called start, any help? Thanks in advance.
Note: I am using storyboards if that makes a difference.