I've created 5 UIView dynamically, which consists of one UILabel and one UIButton each. When I click button, the UIView will setHidden. But it works only on one not other four uiviews.
#interface ViewController : UIViewController
{
NSMutableArray *newViews;
}
#property(nonatomic,retain)IBOutlet UILabel *welcome;
#property(nonatomic,retain)CustomView *custom;
-(void)buttonPressed:(UIButton *)sender;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *name=#"string of length";
int length=[name length];
newViews = [NSMutableArray array];
NSMutableArray *myArray = [NSMutableArray arrayWithObjects:#"cricket", #"golf",#"wrestling", #"FootBall is good game", nil];
int yAxis=44;
int lengthOfArray=[myArray count];
for(int a=0; a<=lengthOfArray; a++){
self.custom= [[CustomView alloc]initWithFrame:CGRectMake(20, yAxis, 100, 44)];
yAxis=yAxis+50;
NSLog(#"yaxis is %i",yAxis);
self.custom.tag=200+a;
[newViews addObject:self.custom];
self.custom.Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, length+70, 30)];
self.custom.button=[[UIButton alloc]initWithFrame:CGRectMake(85,10,12,10)];
UIImage *btnImage = [UIImage imageNamed:#"button_droparrow.png"];
[self.custom.button setImage:btnImage forState:UIControlStateNormal];
[self.custom.button addTarget:self action:#selector(buttonPressed:)forControlEvents:UIControlEventTouchDown];
self.custom.button.tag=self.custom.button.tag+a;
self.custom.backgroundColor=[UIColor greenColor];
custom.Label.text=#"welcome";
custom.Label.backgroundColor = [UIColor yellowColor];
[self.custom addSubview:self.custom.button];
[self.custom addSubview:custom.Label];
[self.view addSubview:self.custom];
}
[self.custom.button addTarget:self action:#selector(buttonPressed:)forControlEvents:UIControlEventTouchDown];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)buttonPressed:(UIButton *)sender
{
[self.custom setHidden:YES];
}
#end
Kindly help me. I am new in iOS development. I need here to create UIView with differrnt reference and that reference assign to UIButton to close that particular UIView but I could not get result out.
You could use UISegmentedControl along with number of xib for each UIView.
In each UIView you can place the required UIControls and link the same.
In the delegate method of SegmentedControl 'indexDidChangeForSegmentedControl:(UISegmentedControl *)sender' on each index remove the earlier UIView and add the required UIView.
In the main header file add the IBOutlet for each UIView
#property (nonatomic, weak) IBOutlet UIView *view1;
#property (nonatomic, weak) IBOutlet UIView *view2;
In .m file in the delegate method 'indexDidChangeForSegmentedControl'
- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender {
NSUInteger index = sender.selectedSegmentIndex;
if (UISegmentedControlNoSegment != index) {
if (currentIndex == index) {
return;
}
currentIndex = index;
switch (index) {
case 0:
{
[self.previousView removeFromSuperview];
[self.view addSubview:view1];
self.previousView = view1;
}
break;
case 1:
{
[self.previousView removeFromSuperview];
[self.view addSubview:view2];
self.previousView = view2;
}
break;
}
}
}
Hope this helps.
If you want to use properties, you will have to make a property for each view. Instead, if you want to create them dynamicaly you could store the references to each view in an array.
The next you should know/do is to add a tag to each button. A tag is just a number, which in this case should reference to its position in the Array.
Then based on the button tag (that you can retrieve from the sender) you can retrieve the proper view/button from the array and change the Hidden property on it.
For example (pseudo code/this wont compile):
Creating the views array
#property (nonatomic, strong) NSMutableArray *views;
In View did load create the views
views = [[NSMutableArray alloc] init];
int nrOfViews = 5;
for(int a=0; a<=nrOfViews; a++){
UIView *view = create UIView here.
UIButton *button = create button here.
[view addSubView: button];
[button setTag: a];
[views addObject: view];
}
reference to the view through the pointer retained in the array, find the right one based on the button tag.
-(void)buttonPressed:(UIButton *)sender
{
UIView *view = [views objectAtIndex: sender.tag]; //using the button tag to identify the right view.
[view setHidden: yes];
}
Try something like this:
- (void) buttonPressed: (UIButton*) sender
{
UIView* view = sender.superview;
view.hidden = YES;
}
You need to make some changes as follows
#property(nonatomic,strong)IBOutlet UILabel *welcome; // new arc code
#property(nonatomic,strong)UIView *custom; // new arc code
self.custom = [[UIView alloc]initWithFrame:CGRectMake(20, yAxis, 100, 44)];
Related
I am new in iOS and I am facing problem regarding to get the value from custom table view cell to view controller. I am using rate view for rating and I am checking if value of rate is less then 3 then it show have to enter text in the text view and I want to get value in view controller
My code is like this
CustomTableviewcell.h
#interface NextTableview : UITableViewCell<RateViewDelegate,UITextViewDelegate>
{
NSString *StatusValue;
UILabel *lbl;
}
#property(nonatomic,strong) IBOutlet UILabel *staticlbl;
#property(nonatomic,strong) IBOutlet UITextView *commenttxtview;
#property(nonatomic,strong) IBOutlet UILabel *Kpiidlbl;
#property (weak, nonatomic) IBOutlet RateView *rateView;
#property (weak, nonatomic) IBOutlet UILabel *statusLabel;
#end
CustomTableviewcell.m
#synthesize rateView,staticlbl,statusLabel,commenttxtview,Kpiidlbl;
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
commenttxtview.layer.borderWidth = 0.70f;
commenttxtview.layer.borderColor = [[UIColor blackColor] CGColor];
commenttxtview.delegate=self;
UIToolbar* doneToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
doneToolbar.barStyle = UIBarStyleBlackTranslucent;
doneToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonClickedDismissKeyboard)],
nil];
[doneToolbar sizeToFit];
commenttxtview.inputAccessoryView = doneToolbar;
lbl = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0,90.0, 34.0)];
[lbl setText:#"Enter Text"];
[lbl setFont:[UIFont systemFontOfSize:12]];
[lbl setBackgroundColor:[UIColor clearColor]];
[lbl setTextColor:[UIColor lightGrayColor]];
commenttxtview.delegate = self;
[commenttxtview addSubview:lbl];
statusLabel.hidden=YES;
commenttxtview.hidden=YES;
// Do any additional setup after loading the view from its nib.
self.rateView.notSelectedImage = [UIImage imageNamed:#"not_selected_star#2x.png"];
self.rateView.halfSelectedImage = [UIImage imageNamed:#"half_selected_star#2x.png"];
self.rateView.fullSelectedImage = [UIImage imageNamed:#"selected_star#2x.png"];
self.rateView.rating = 0;
self.rateView.editable = YES;
self.rateView.maxRating = 5;
self.rateView.delegate = self;
Kpiidlbl.hidden=YES;
}
-(void)doneButtonClickedDismissKeyboard
{
[commenttxtview resignFirstResponder];
// commenttxtview.hidden=YES;
}
- (void)textViewDidEndEditing:(UITextView *)theTextView
{
if (![commenttxtview hasText]) {
lbl.hidden = NO;
}
}
- (void) textViewDidChange:(UITextView *)textView
{
if(![commenttxtview hasText]) {
lbl.hidden = NO;
}
else{
lbl.hidden = YES;
}
}
- (void)rateView:(RateView *)rateView ratingDidChange:(int)rating {
self.statusLabel.text = [NSString stringWithFormat:#"%d", rating];
NSLog(#"Rating value =%#",self.statusLabel.text);
StatusValue=statusLabel.text;
NSLog(#"Status Value String =%#",StatusValue);
// Hear I am getting value of rating..in StatusValue..
int status=[StatusValue intValue];
if(status<=3)
{
commenttxtview.hidden=NO;
}
else{
commenttxtview.hidden=YES;
}
}
How can I get label and textview value in viewcontroller and I want to set rate view value to rate view after reload table.
Hear in the Image i am getting five star and If I click on less then 3 star it should have to write comment.I am taking rate value in the label.How can I get both label and textvalue in view controller.Please tell me to update question if you want more data.Thanks in Advance!
So write this in your CustomTableViewCell.h
#property(nonatomic,assign)NSInteger selectedRating;
everytime when the rating is updated in the Cell, you have to change the value of this variable.
In the viewController it depends on when you want to get the value of this cell. For example in this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
CustomTableViewCell *yourCell = (CustomerTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%lu",yourCell.selectedRating);
}
Let me know if this was helpful!
Another way without a variable is to read the NSString in the statusLabel and change the string to a NSInteger variable...
If you are using your delegate...
Then implement the delegate RateViewDelegatein the viewController. The delegate is called in the class to which it is assigned...
Try this
You have to add the #property (nonatomic, weak) NSObject<RateViewDelegate>* delegate;
to the header file of your CustomTableViewCell.h in the method
-(UITableViewCell) cellForRowAtIndexPath....
you have to assign the delegate like this
cell.delegate = self;
Now modify your cell delegate method to this
- (void)rateView:(RateView *)rateView ratingDidChange:(int)rating {
self.statusLabel.text = [NSString stringWithFormat:#"%d", rating];
NSLog(#"Rating value =%#",self.statusLabel.text);
StatusValue=statusLabel.text;
NSLog(#"Status Value String =%#",StatusValue);
// Hear I am getting value of rating..in StatusValue..
int status=[StatusValue intValue];
if(status<=3)
{
commenttxtview.hidden=NO;
}
else{
commenttxtview.hidden=YES;
}
if([self.delegate respondsToSelector:#selector(rateView:ratingDidChange:)]){
[self.delegate rateView:rateView ratingDidChange:rating];
}
}
Our iPhone app currently supports IOS 8/9/10. I am having difficulty supporting voice over accessibility for a custom UITableViewCell. I have gone through the following SO posts, but none of the suggestions have worked. I want individual components to be accessible.
Custom UITableview cell accessibility not working correctly
Custom UITableViewCell trouble with UIAccessibility elements
Accessibility in custom drawn UITableViewCell
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/iPhoneAccessibility/Making_Application_Accessible/Making_Application_Accessible.html#//apple_ref/doc/uid/TP40008785-CH102-SW10
http://useyourloaf.com/blog/voiceover-accessibility/
Unfortunately for me, the cell is not detected by the accessibility inspector. Is there a way to voice over accessibility to pick up individual elements within the table view cell? When debugging this issue on both device and a simulator, I found that the XCode calls isAccessibleElement function. When the function returns NO, then the rest of the methods are skipped. I am testing on IOS 9.3 in XCode.
My custom table view cell consists of a label and a switch as shown below.
The label is added to the content view, while the switch is added to a custom accessory view.
The interface definition is given below
#interface MyCustomTableViewCell : UITableViewCell
///Designated initializer
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier;
///Property that determines if the switch displayed in the cell is ON or OFF.
#property (nonatomic, assign) BOOL switchIsOn;
///The label to be displayed for the alert
#property (nonatomic, strong) UILabel *alertLabel;
#property (nonatomic, strong) UISwitch *switch;
#pragma mark - Accessibility
// Used for setting up accessibility values. This is used to generate accessibility labels of
// individual elements.
#property (nonatomic, strong) NSString* accessibilityPrefix;
-(void)setAlertHTMLText:(NSString*)title;
#end
The implementation block is given below
#interface MyCustomTableViewCell()
#property (nonatomic, strong) UIView *customAccessoryView;
#property (nonatomic, strong) NSString *alertTextString;
#property (nonatomic, strong) NSMutableArray* accessibleElements;
#end
#implementation MyCustomTableViewCell
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if(self = [super initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:reuseIdentifier]) {
[self configureTableCell];
}
return self;
}
- (void)configureTableCell
{
if (!_accessibleElements) {
_accessibleElements = [[NSMutableArray alloc] init];
}
//Alert label
self.alertLabel = [[self class] makeAlertLabel];
[self.contentView setIsAccessibilityElement:YES];
//
[self.contentView addSubview:self.alertLabel];
// Custom AccessoryView for easy styling.
self.customAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
[self.customAccessoryView setIsAccessibilityElement:YES];
[self.contentView addSubview:self.customAccessoryView];
//switch
self.switch = [[BAUISwitch alloc] initWithFrame:CGRectZero];
[self.switch addTarget:self action:#selector(switchWasFlipped:) forControlEvents:UIControlEventValueChanged];
[self.switch setIsAccessibilityElement:YES];
[self.switch setAccessibilityTraits:UIAccessibilityTraitButton];
[self.switch setAccessibilityLabel:#""];
[self.switch setAccessibilityHint:#""];
self.switch.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.customAccessoryView addSubview:self.switch];
}
+ (UILabel *)makeAlertLabel
{
UILabel *alertLabel = [[UILabel alloc] initWithFrame:CGRectZero];
alertLabel.backgroundColor = [UIColor clearColor];
alertLabel.HTMLText = #"";
alertLabel.numberOfLines = 0;
alertLabel.lineBreakMode = LINE_BREAK_WORD_WRAP
[alertLabel setIsAccessibilityElement:YES];
return alertLabel;
}
-(void)setAlertHTMLText:(NSString*)title{
_alertTextString = [NSString stringWithString:title];
[self.alertLabel setText:_alertTextString];
}
- (BOOL)isAccessibilityElement {
return NO;
}
// The view encapsulates the following elements for the purposes of
// accessibility.
-(NSArray*) accessibleElements {
if (_accessibleElements && [_accessibleElements count] > 0) {
[_accessibleElements removeAllObjects];
}
// Fetch a new copy as the values may have changed.
_accessibleElements = [[NSMutableArray alloc] init];
UIAccessibilityElement* alertLabelElement =
[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
//alertLabelElement.accessibilityFrame = [self convertRect:self.contentView.frame toView:nil];
alertLabelElement.accessibilityLabel = _alertTextString;
alertLabelElement.accessibilityTraits = UIAccessibilityTraitStaticText;
[_accessibleElements addObject:alertLabelElement];
UIAccessibilityElement* switchElement =
[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
// switchElement.accessibilityFrame = [self convertRect:self.customAccessoryView.frame toView:nil];
switchElement.accessibilityTraits = UIAccessibilityTraitButton;
// If you want custom values, just override it in the invoking function.
NSMutableString* accessibilityString =
[NSMutableString stringWithString:self.accessibilityPrefix];
[accessibilityString appendString:#" Switch "];
if (self.switchh.isOn) {
[accessibilityString appendString:#"On"];
} else {
[accessibilityString appendString:#"Off"];
}
switchElement.accessibilityLabel = [accessibilityString copy];
[_accessibleElements addObject:switchElement];
}
return _accessibleElements;
}
// In case accessibleElements is not initialized.
- (void) initializeAccessibleElements {
_accessibleElements = [self accessibleElements];
}
- (NSInteger)accessibilityElementCount
{
return [_accessibleElements count]
}
- (id)accessibilityElementAtIndex:(NSInteger)index
{
[self initializeAccessibleElements];
return [_accessibleElements objectAtIndex:index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element
{
[self initializeAccessibleElements];
return [_accessibleElements indexOfObject:element];
}
#end
First of all, from the pattern you described, I'm not sure why you would want to differentiate between different elements in a cell. Generally, Apple keeps every cell a single accessibility element. A great place to see the expected iOS VO behavior for cells with labels and switches is in Settings App.
If you still believe the best way to handle your cells is to make them contain individual elements, then that is actually the default behavior of a cell when the UITableViewCell itself does not have an accessibility label. So, I've modified your code below and run it on my iOS device (running 9.3) and it works as you described you would like.
You'll notice a few things.
I deleted all the custom accessibilityElements code. It is not necessary.
I deleted the override of isAccessibilityElement on the UITableViewCell subclass itself. We want default behavior.
I commented out setting the content view as an accessibilityElement -- we want that to be NO so that the tree-builder looks inside of it for elements.
I set customAccessoryView's isAccessibilityElement to NO as well for the same reason as above. Generally, NO says "keep looking down the tree" and YES says "stop here, this is my leaf as far as accessibility is concerned."
I hope this is helpful. Once again, I do really encourage you to mimic Apple's VO patterns when designing for Accessibility. I think it's awesome that you're making sure your app is accessible!
#import "MyCustomTableViewCell.h"
#interface MyCustomTableViewCell()
#property (nonatomic, strong) UIView *customAccessoryView;
#property (nonatomic, strong) NSString *alertTextString;
#property (nonatomic, strong) NSMutableArray* accessibleElements;
#end
#implementation MyCustomTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if(self = [super initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:reuseIdentifier]) {
[self configureTableCell];
}
return self;
}
// just added this here to get the cell to lay out for myself
- (void)layoutSubviews {
[super layoutSubviews];
const CGFloat margin = 8;
CGRect b = self.bounds;
CGSize labelSize = [self.alertLabel sizeThatFits:b.size];
CGFloat maxX = CGRectGetMaxX(b);
self.alertLabel.frame = CGRectMake(margin, margin, labelSize.width, labelSize.height);
CGSize switchSize = [self.mySwitch sizeThatFits:b.size];
self.customAccessoryView.frame = CGRectMake(maxX - switchSize.width - margin * 2, b.origin.y + margin, switchSize.width + margin * 2, switchSize.height);
self.mySwitch.frame = CGRectMake(margin, 0, switchSize.width, switchSize.height);
}
- (void)configureTableCell
{
//Alert label
self.alertLabel = [[self class] makeAlertLabel];
//[self.contentView setIsAccessibilityElement:YES];
//
[self.contentView addSubview:self.alertLabel];
// Custom AccessoryView for easy styling.
self.customAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
[self.customAccessoryView setIsAccessibilityElement:NO]; // Setting this to NO tells the the hierarchy builder to look inside
[self.contentView addSubview:self.customAccessoryView];
self.customAccessoryView.backgroundColor = [UIColor purpleColor];
//switch
self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
//[self.mySwitch addTarget:self action:#selector(switchWasFlipped:) forControlEvents:UIControlEventValueChanged];
[self.mySwitch setIsAccessibilityElement:YES]; // This is default behavior
[self.mySwitch setAccessibilityTraits:UIAccessibilityTraitButton]; // No tsure why this is here
[self.mySwitch setAccessibilityLabel:#"my swich"];
[self.mySwitch setAccessibilityHint:#"Tap to do something."];
self.mySwitch.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.customAccessoryView addSubview:self.mySwitch];
}
+ (UILabel *)makeAlertLabel
{
UILabel *alertLabel = [[UILabel alloc] initWithFrame:CGRectZero];
alertLabel.backgroundColor = [UIColor clearColor];
alertLabel.text = #"";
alertLabel.numberOfLines = 0;
[alertLabel setIsAccessibilityElement:YES];
return alertLabel;
}
-(void)setAlertHTMLText:(NSString*)title{
_alertTextString = [NSString stringWithString:title];
[self.alertLabel setText:_alertTextString];
}
#end
I am trying to achieve a right to left iCarousel object with a fade on both sides.
So i imported the GtiHub Project into My application, Assigned a UIView to iCarousel...Linked that to an IBOutLet on my MainViewController and passed the Delegate as well as the DataSource just like the UITableViewController.
Though it will not show up and i am unsure of what could be causing this issue.
My iCarousel DataSource is is an NSMutableArray *items; designed like so:
for (int i = 0; i < 100; i++)
{
[_items addObject:#(i)];
}
I am initializing the iCarousel in the ViewDidLoad like below
- (void)viewDidLoad
{
[super viewDidLoad];
//Initialize Carousel
_carousel = [[iCarousel alloc] init];
_carousel.delegate = self;
_carousel.dataSource = self;
//Carousel Testing Data
for (int i = 0; i < 100; i++)
{
[_items addObject:#(i)];
}
//configure carousel
_carousel.type = iCarouselTypeRotary;
}
My Delegate Methods for Carousel are below:
#pragma mark -
#pragma mark iCarousel methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
//return the total number of items in the carousel
return [_items count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.font = [label.font fontWithSize:50];
label.tag = 1;
[view addSubview:label];
}
else
{
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
}
label.text = [_items[index] stringValue];
return view;
}
- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
switch (option)
{
case iCarouselOptionFadeMin:
return -0.2;
case iCarouselOptionFadeMax:
return 0.2;
case iCarouselOptionFadeRange:
return 2.0;
default:
return value;
}
}
Everything from the storyboard seems to be connected and the data should be presenting itself, what is wrong and how can i fix this issue?
Since you have the DataSource array (_items) setup after the view gets loaded:
Make sure that the carousel view in your storyboard does have the IBOutlet to the controller, but NOT the 'Delegate' and 'DataSource' linked to the File's Owner (Controller or view).
Set the _carousel.delegate and _carousel.dataSource to 'self' only After you initialize and update the dataSource array (_items in this case).
Place breakpoints to check whether the iCarousel Datasource and Delegate methods are being called or not.
If the methods are not called, check whether the controller follows the iCarousel protocols like this:
#interface yourViewController : UIViewController <iCarouselDataSource, iCarouselDelegate>
Obviously you'll have to
#import "iCarousel.h"
UPDATE: In your viewDidLoad, you have
_carousel = [[iCarousel alloc] init];
looks like you forgot to set a frame for _carousel and add it as a subView.
To get the imageView reference, try this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
imageView.image = [UIImage imageNamed:#"page.png"];
view = imageView;
I have been trying to do this simple thing : adding an action to a simple custom view. I have looked over the internet and found two "easy" solution :
UITapGestureRecognizer
UIButton
I want to do this programmatically and I just need to handle the tap.
Here is my code so far, I've tried both solutions separately and together and it doesn't work !
.m
#import "AreaView.h"
#implementation AreaView
#define GREY 27.0/255.0
#define PINK_R 252.0/255.0
#define PINK_G 47.0/255.0
#define PINK_B 99.0/255.0
- (id) initWithFrame:(CGRect)frame imageName:(NSString *)imageName areaName:(NSString *)areaName minimumSpending:(int)minimumSpending andCapacity:(int)capacity
{
self = [self initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithRed:GREY green:GREY blue:GREY alpha:1];
self.userInteractionEnabled=YES;
//Init variables
_areaName=areaName;
_capacity=capacity;
_minimumSpending=minimumSpending;
//Image view
_logoImageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 4, 66, 50)];
//_logoImageView.image = [UIImage imageNamed:imageName];
_logoImageView.backgroundColor = [UIColor grayColor];
//Label
_areaNameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 54, 76, 18)];
_areaNameLabel.textAlignment = NSTextAlignmentCenter;
_areaNameLabel.textColor = [UIColor whiteColor];
_areaNameLabel.font = [UIFont systemFontOfSize:12.0];
_areaNameLabel.text = areaName;
//button
_button = [[UIButton alloc]initWithFrame:self.bounds];
_button.userInteractionEnabled=YES;
_button.backgroundColor=[UIColor yellowColor];
[_button addTarget:self action:#selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
//tap gesture racognizer
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[self addGestureRecognizer:tapRecognizer];
[self addSubview:_logoImageView];
[self addSubview:_areaNameLabel];
[self addSubview:_button];
}
return self;
}
-(void)handleTap:(UIButton *)button
{
NSLog(#"tapped!");
}
-(void)tapped:(UITapGestureRecognizer *)recognizer
{
NSLog(#"tapped!");
}
#end
.h
#import <UIKit/UIKit.h>
#interface AreaView : UIView <UIGestureRecognizerDelegate>
#property (nonatomic) UIImageView *logoImageView;
#property (nonatomic) UILabel *areaNameLabel;
#property (nonatomic) NSString *areaName;
#property (nonatomic) int minimumSpending;
#property (nonatomic) int capacity;
- (id) initWithFrame:(CGRect)frame imageName:(NSString *)imageName areaName:(NSString *)areaName minimumSpending:(int)minimumSpending andCapacity:(int)capacity;
#property (nonatomic, strong) UIButton *button;
#end
Thanks for your help!
EDIT
The problem is that both handleTap and tapped are never fired even if I comment the button solution or the tap gesture one to test them separately. For the button implementation, I can see it on my interface but clicking on it does nothing.
My UIView is then added programmatically several times (for several views) in a UIScrollview.
EDIT 2
The problem is more complicate than that. The custom view is inside a scrollview which is inside another different custom view whose main function is to rewrite hittest, so that touches on this view are held by the scrollview. (Here is the purpose of all that).
It seems that as long as hittest is involved, it doesn't work.
Implement this delegate method, which will help you.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
id touchedView = gestureRecognizer.view;
if ([touchedView isKindOfClass:[UIButton class]])
{
return NO; //It won't invoke gesture method, But it'll fire button method.
}
return YES;
}
I'm not sure why your UIButton and UITapGestureRecognizer selectors aren't firing. However another option to handle taps on a view is to simply override the touchesEnded:withEvent method:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//handle a tap
}
That way, you won't have to create a UIButton or a UITapGestureRecognizer object at all.
When someone votes down the question... kindly please also comment why you had voted it down.
I have a UIView (myHolderView) on which I want to place 9 or more other views.
I added some UIView (MyView) instances to an NSMutableArray of 9 elements (MyArray).
MyView has a label (UILabel) on it. Can someone please assist how to get label's text using MyArray?
Note:
I am seeing the UIViews added to main holder view and getting labels on it.
initWithFrame:(v,v,v,v) number: (value) is the init method I had overloaded init with.
//These two are declared as global variable
NSMutableArray *tiles;
MyView *tile;
#implementation ViewController
#synthesize myHolderView;
- (void)viewDidLoad
{
[super viewDidLoad];
tiles=[[NSMutableArray alloc]initWithCapacity:9];
for (int xIndex=0; xIndex<3; xIndex++)
{
for(int yIndex=0; yIndex<3; yIndex++)
{
static int label=0;
[tiles addObject:[[MyView alloc]initWithFrame:CGRectMake(value,value,value,value)
number:[[NSString alloc] initWithFormat:#"%d",label+1]]];
[self.myHolderView addSubview:tiles[label]];
//Now - when I want to print the labels onto Console as NSLog messages
//it is printing null
MyView *n=[[MyView alloc]init];
n=(MyView *)[tiles objectAtIndex:label++];
NSLog(#"%#---", n.myLabel.text);
//this also does not work. Definitely wrong dereferencing
// NSLog(#"%#---", (MyView*) [tiles ObjectAtIndex:1].mylabel.text);
//label++;
}
}
}
Please help
how to dereference NSMuableArray objects to the type what we want (the
type we know it exactly)
MyView:
- (id)initWithFrame:(CGRect)frame number:(NSString *)num;
{
self = [super initWithFrame:frame];
if (self) {
MyView *tile = [[[NSBundle mainBundle] loadNibNamed:#"XView" owner:self options:nil] objectAtIndex:0];
tile.myLabel.text=num;
[self addSubview:tile];
}
return self;
}
According to your comment, you want to add some view to your holderview. Later, you want to change text in particular view. So I suggest some way. I think, It will help you..
1) create and Add subview to your holder view
for (int xIndex=0; xIndex<9; xIndex++)
{
MyView *subView = [[MyView alloc]initWithFrame:CGRectMake(value,value,value,value)
number:[[NSString alloc] initWithFormat:#"%d",somecount+1]]]; // doesn't know why do you try this..
subView.tag = xIndex;
[self.myHolderView addSubview: subView];
}
2) Get particular subview with tag value.(No need to maintain any other array in your view controller)
After some time, you want to change text in particular view. Just try it..
MyView *subView = [self.myHolderView viewWithTag:index]; // as like, you access array
subView.myLabel.text = yourUpdateText;
#import "ViewController.h"
#interface MyView : UIView
#property UILabel *myLabel;
- (id) initWithFrame: (CGRect) rect number: (NSString *) string;
#end
#implementation MyView
- (id) initWithFrame: (CGRect) frame number: (NSString *) number {
self = [super initWithFrame:frame];
if (!self) return nil;
// Any things here
// Are you initialized label?
_myLabel = [UILabel new];
[_myLabel setText:number];
[self addSubview:_myLabel];
return self;
}
#end
#interface ViewController ()
#property UIView *myHolderView;
#end
NSMutableArray *tiles;
MyView *tile;
#implementation ViewController
#synthesize myHolderView;
- (void)viewDidLoad {
[super viewDidLoad];
tiles=[[NSMutableArray alloc]initWithCapacity:9];
int value = 1, label = 0;
myHolderView = [UIView new];
for (int xIndex=0; xIndex<3; xIndex++) {
for(int yIndex=0; yIndex<3; yIndex++) {
NSString *number = [[NSString alloc] initWithFormat:#"%d",label+1];
MyView *myView = [[MyView alloc]initWithFrame:CGRectMake(value,value,value,value)
number:number];
[tiles addObject:myView];
[self.myHolderView addSubview:tiles[label]];
//Now - when I want to print the labels onto Console as NSLog messages
//it is printing number
MyView *n=(MyView *)[tiles objectAtIndex:label++];
NSLog(#"%#---", n.myLabel.text);
}
}
// And without tiles array
for (UIView *subView in [myHolderView subviews])
for (UIView *subSubView in [subView subviews])
if ([subSubView isKindOfClass:[UILabel class]])
NSLog(#"%#", [(UILabel *) subSubView text]);
}
#end
Your problem is nothing to do with arrays or dereferencing. It's a logical issue because you are creating multiple views and nesting them.
Change the implementation of MyView:
- (id)initWithFrame:(CGRect)frame number:(NSString *)num;
{
self = [[[NSBundle mainBundle] loadNibNamed:#"XView" owner:self options:nil] objectAtIndex:0];
self.frame = frame;
self.myLabel.text = num;
return self;
}
Try something like this (typed inline so watch for issues):
- (void)viewDidLoad
{
[super viewDidLoad];
tiles = [[NSMutableArray alloc] initWithCapacity:9];
NSUInteger counter = 0;
for (int xIndex=0; xIndex<3; xIndex++)
{
for(int yIndex=0; yIndex<3; yIndex++)
{
MyView *newView = [[MyView alloc] initWithFrame:CGRectMake(value,value,value,value) number:[[NSString alloc] initWithFormat:#"%d", counter+1]]];
[self.myHolderView addSubview:newView];
[tiles addObject:newView];
MyView *logView = (MyView *)[tiles objectAtIndex:counter];
NSLog(#"view %d is %#---", counter, logView.myLabel.text);
counter++;
}
}
}