UIView strange behaviour with BOOL - ios

I've made my custom UIView that I'm representing on UIViewController. View is presented on screen, but BOOL that I've setted on that instance of UIView to YES is not recognized.
Code:
UIView implementation:
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self createInterface];
}
return self;
}
-(void)createInterface
{
if (self.isSplash == YES) {
self.backgroundColor = [UIColor clearColor];
}
else {
self.backgroundColor = DARK_BLUE;
[self setupTimer];
}
....
ViewController:
self.sponsorView = [[SponsorMechanismView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.logo.frame)+10, SCREEN_WIDTH, 100)];
self.sponsorView.isSplash = YES;
[self.view addSubview:self.sponsorView];
So, I set BOOL to YES, but in this UIView it is always NO.

As Fabio said, createInterface has already been executed.
What you can do is create your own init function. Something like this :
- (id)initWithFrame:(CGRect)frame isSplash(BOOL)isSplash
{
self = [super initWithFrame:frame];
self.isSplash = isSplash;
if (self) {
[self createInterface];
}
return self;
}
And the call of the function will be like :
self.sponsorView = [[SponsorMechanismView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.logo.frame)+10, SCREEN_WIDTH, 100) isSplash:YES];

- (id)initWithFrame:(CGRect)frame AndIsFlash:(BOOL)isFlash{
self = [super initWithFrame:frame];
if (self) {
[self createInterfaceAndisFlash:isFlash];
}
return self;
}
-(void)createInterfaceAndisFlash:(BOOL)isFlash
{
if (isFlash == YES) {
self.backgroundColor = [UIColor clearColor];
}
else {
self.backgroundColor = [UIColor blueColor];
}
}
Hope you Got an Idea.

As mentioned in the comments:
The creatInterface method has already been executed when you set isSplash.
You can solve this by overwriting the setter of isSplash and calling createInterface there.
Code example here:
- (void)setIsSplash:(BOOL)isSplash
{
if (isSplash != _isSplash)
{
_isSplash = isSplash;
[self createInterface];
}
}

Related

UIDropInteractionDelegate not being called

I have a DropAreaViewController in my app. Inside this controller I run the following code:
- (void)viewDidLoad {
[super viewDidLoad];
UIDropInteraction *interaction = [[UIDropInteraction alloc] initWithDelegate:self];
[self.view addInteraction:interaction];
}
- (BOOL)dropInteraction:(UIDropInteraction *)dropInteraction canHandleSession:(nonnull id<UIDropSession>)session {
NSLog(#"canHandleSession called");
return true;
}
- (UIDropProposal *)dropInteraction:(UIDropInteraction *)dropInteraction sessionDidUpdate:(nonnull id<UIDropSession>)session {
NSLog(#"sessionDidUpdate");
if (session.localDragSession != nil) {
NSLog(#"is localDragSession");
return [[UITableViewDropProposal alloc] initWithDropOperation:UIDropOperationMove intent:UITableViewDropIntentInsertAtDestinationIndexPath];
} else {
return [[UITableViewDropProposal alloc] initWithDropOperation:UIDropOperationCancel];
}
}
- (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id<UIDropSession>)session {
self.view.backgroundColor = [UIColor redColor];
}
Now, in another viewcontroller I add this controller:
DropAreaViewController *davc = [[DropAreaViewController alloc] init];
davc.view.frame = CGRectMake(0, 0, 100, 100);
[self.view addSubview:davc.view];
None of the drops are being registered though. I get not logs at all when I hover a drop on top of the square. Any ideas?

UIView not Showing in Main View Controller

Hi all I'm implementing in my main ViewController some UIView custom class .. All are shown but only the KPHomeInfluenceUser is not visible .. Definitely it is a stupid question or lack of attention but you can explain why you do not see it ?? What am I doing is a wrong way to implement UIView Custom Class? If my method is wrong you can describe the correct method? I've seen many programmers implement classes this way.... Excuse me for stupid question
- (void)viewDidLoad {
[super viewDidLoad];
[self scrollView];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.calendar clearAllDataToHomeCalendarAndReloadData];
[self.calendar scrollHomeCalendarToCurrentDayAndMonth];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] init];
_scrollView.backgroundColor = [UIColor clearColor];
_scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.scrollView];
[self.scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
[self.scrollView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
[self.scrollView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
[self calendar];
[self influenceUser];
[self homeBottom];
}
return _scrollView;
}
-(KPHomeCalendar *)calendar {
if (!_calendar) {
_calendar = [[KPHomeCalendar alloc] init];
_calendar.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.calendar];
[self.calendar.topAnchor constraintEqualToAnchor:self.baseUserPhoto.topAnchor constant:-5].active = YES;
[self.calendar.leftAnchor constraintEqualToAnchor:self.baseUserPhoto.rightAnchor constant:10].active = YES;
[self.calendar.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-10].active = YES;
[self.calendar.heightAnchor constraintEqualToConstant:85].active = YES;
}
return _calendar;
}
-(KPHomeInfluenceUser *)influenceUser {
KPHomeInfluenceUser *influence = [[KPHomeInfluenceUser alloc] init];
influence.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:influence];
[influence.topAnchor constraintEqualToAnchor:self.calendar.bottomAnchor constant:0].active = YES;
[influence.leftAnchor constraintEqualToAnchor:self.scrollView.leftAnchor constant:10].active = YES;
[influence.rightAnchor constraintEqualToAnchor:self.scrollView.rightAnchor constant:-10].active = YES;
[influence.heightAnchor constraintEqualToConstant:100].active = YES;
return influence;
}

Creating a receipt style UIView

I am attempting to create a view to show a list of items and prices using two UILabels in a UIView.
In my UIViewController I call my subview LineItemView and pass data, and return the UIView to the main view that will hold the subviews.
Though my view is returning empty. The strings are null.
ViewController.m
#import "LineItemView.h"
//...
#property (weak, nonatomic) IBOutlet UIView *viewCharges;
//...
- (void)viewDidLoad {
[super viewDidLoad];
[self loadData];
}
- (void) loadData {
//Here we will fill in the viewCharges view
LineItemView * view = [[LineItemView alloc]init];
view.linePrice = #"1.00";
view.lineItem = #"Something";
[self.viewCharges addSubview:view];
}
LineItemView.h
#interface LineItemView : UIView {
UILabel * lblLineItem, *lblLinePrice;
}
#property (nonatomic,strong) NSString* lineItem;
#property (nonatomic,strong) NSString* linePrice;
LineItemView.m
#define LABEL_MINIMUM_HEIGHT 32
#define VERTICAL_MARGIN 5
#define HORIZONTAL_MARGIN 10
#implementation LineItemView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self createUI];
[self updateData];
NSLog(#"\n\n\n Line Item: %# Price: %# \n\n\n", self.lineItem, self.linePrice);
}
return self;
}
-(void) createUI {
lblLineItem = [[UILabel alloc] initWithFrame:CGRectZero];
lblLineItem.backgroundColor = [UIColor greenColor];
[self addSubview:lblLineItem];
lblLinePrice = [[UILabel alloc] initWithFrame:CGRectZero];
lblLinePrice.backgroundColor = [UIColor yellowColor];
[self addSubview:lblLinePrice];
}
- (void) updateLayout {
lblLineItem.frame = CGRectMake(HORIZONTAL_MARGIN, VERTICAL_MARGIN, 300, 35);
lblLinePrice.frame = CGRectMake(lblLineItem.frame.origin.x + lblLineItem.frame.size.width + HORIZONTAL_MARGIN, VERTICAL_MARGIN, 80, 35);
}
- (void) updateData {
lblLineItem.text = self.lineItem;
lblLinePrice.text = [NSString stringWithFormat:#"%0.2f", [self.linePrice floatValue]];
}
- (void) layoutSubviews {
[super layoutSubviews];
[self updateLayout];
}
What am I doing wrong?
If I want to continue calling LineItemView, how do I ensure that it is added below the previous one and ensure the viewCharges size is readjusted to fit all the subviews?
Solution using setters:
#implementation LineItemView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self createUI];
}
return self;
}
-(void) createUI {
lblLineItem = [[UILabel alloc] initWithFrame:CGRectZero];
lblLineItem.backgroundColor = [UIColor greenColor];
[self addSubview:lblLineItem];
lblLinePrice = [[UILabel alloc] initWithFrame:CGRectZero];
lblLinePrice.backgroundColor = [UIColor yellowColor];
[self addSubview:lblLinePrice];
}
- (void) updateLayout {
lblLineItem.frame = CGRectMake(HORIZONTAL_MARGIN, VERTICAL_MARGIN, 300, 35);
lblLinePrice.frame = CGRectMake(lblLineItem.frame.origin.x + lblLineItem.frame.size.width + HORIZONTAL_MARGIN, VERTICAL_MARGIN, 80, 35);
}
- (void) layoutSubviews {
[super layoutSubviews];
[self updateLayout];
}
- (void)setLineItem:(NSSTring *)lineItem {
_lineItem = lineItem;
lblLineItem.text = self.lineItem;
}
- (void)setLinePrice:(NSNumber *)linePrice {
_linePrice = linePrice;
lblLinePrice.text = [NSString stringWithFormat:#"%0.2f", [self.linePrice floatValue]];
}

UIScrollview does not react to any touch?

I am trying to do a simple scroll, but the views do not move after a touch, I am not sure why, the scrollview should handle the gesture, but something might be missing. Would someone know where?
Here is the code : I create a small horizontal scroll view, with some views inside. The views appear well, I am testing it on a device for the touch :
- (void)viewDidLoad {
[super viewDidLoad];
//horizontal scroll view
HorizScroll *ho = [[HorizScroll alloc] initWithFrame:CGRectMake(0, 0, 500, 100)];
for ( int i=0; i<3; i++){
MyView* mv = [[MyView alloc] init];
[ho addSubview:mv];
}
//ho.zoomScale = 0.3f;
[self.view addSubview:ho];
}
#implementation HorizScroll
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
}
return self;
}
-(void)addSubview:(UIView *)view{
[super addSubview:view];
NSUInteger numSubviews = self.subviews.count;
[view setFrame:CGRectMake(CGRectGetWidth(view.bounds)*(numSubviews),
0,
CGRectGetWidth(view.bounds),
CGRectGetHeight(view.bounds) )];
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds) )];
}
#implementation MyView
-(int)getRandomNumberBetween:(int)from to:(int)pto {
return (int)(from + arc4random() % (pto-from+1));
}
-(instancetype)init{
if ( self = [super init] ){
CGFloat red = [self getRandomNumberBetween:1 to:255];
self.backgroundColor = [UIColor colorWithRed:red/256.0
green:[self getRandomNumberBetween:1 to:255]/256.0
blue:[self getRandomNumberBetween:1 to:255]/256.0
alpha:1.0];
}
return self;
}
-(instancetype)initWithFrame:(CGRect)frame{
if ( self = [super initWithFrame:frame] ){
self.frame = CGRectMake(counterX, 0, 100, 100);
counterX += 50;
}
return self;
}
You need to set contentSize of scrollview to be larger than its frame size. so add this line after [self.view addSubview:ho].
ho.contentSize = CGSizeMake(501.f, 100.f);
or before [self.view addSubview:ho] and comment out the line:
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds))];
which is not necessary since you can set it after all subviews are added.

Sublayer only draws when created in initWithFrame, not initWithCoder

I have a custom view with a sublayer (CAShapeLayer) and subview (UILabel). When I create the layer in initWithCoder and set the background color, it always shows up as black. However, if I move the code into initWithFrame, the color shows up successfully.
Are we not supposed to create sublayers in initWithCoder?
Here is the only way I can get my code to work:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.colorLayer = [CAShapeLayer layer];
self.colorLayer.opacity = 1.0;
[self.layer addSublayer:self.colorLayer];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.textLabel = [[UILabel alloc] initWithFrame:self.bounds];
self.textLabel.font = [UIFont primaryBoldFontWithSize:12];
self.textLabel.textColor = [UIColor whiteColor];
self.textLabel.textAlignment = NSTextAlignmentCenter;
self.textLabel.backgroundColor = [UIColor clearColor];
[self addSubview:self.textLabel];
}
return self;
}
- (void)drawRect:(CGRect)rect {
//Custom drawing of sublayer
}
UPDATE:
Turns out in my drawRect I was setting the fill color wrong. I should have used colorLayer.fillColor = myColor.CGColor instead of [myColor setFill] then [path fill]
The difference between initWithFrame: and initWithCoder: is that initWithCoder: is called when the view is created from storyboard/nib.
If you add it programatically, for example:
UIView *v = [[UIView alloc] initWithFrame:...];
[self.view addSubview:v];
initWithFrame: is called.
The good idea is to create base init method and call it in both init. In that way the initialisation sets up all of the properties in both scenario, when the view is added programatically or in storyboard.
For example:
-(void)baseInit {
self.colorLayer = [CAShapeLayer layer];
self.colorLayer.opacity = 1.0;
//... other initialisation
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self baseInit];
}
return self;
}

Resources