Unable to configure voice over accessibility for a custom UITableViewCell - ios

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

Related

Reuse xib in different screens

I have 4 screens that have one almost the same view:
And one screen have the same view but with slightly different UI:
So, my question: Can I use one xib and adapt states (active, inactive) and change ui for different screen? How I can do it?
Here is an example of this kind of class
In Your .m file of custom XIB class if you are using objective-c.
- (void)foo:(NSString*)labelText andButtonText:(NSString*)buttonTitle {
//Do your code here for some screen like change labels and button text
}
- (void)bar:(NSString*)labelText andButtonText:(NSString*)buttonTitle {
//Do your code here for some another screen and change labels and button text
}
In Your .h file of custom XIB class if you are using objective-c.
- (void)foo:(NSString*)labelText andButtonText:(NSString*)buttonTitle;
- (void)bar:(NSString*)labelText andButtonText:(NSString*)buttonTitle;
In your view controller where you want to display the custom UI
Create an instance of your xib or add through interfacebuilder
And On your instance of custom class call the method as required.
Below is a class I've used in one of my project to get a clear understanding.
#import <UIKit/UIKit.h>
#import "DYRateView.h"
#interface LevelAndRankDetails : UIView
#property (nonatomic, strong) IBOutlet UIView* contentView;
#property (nonatomic, strong) IBOutlet UIView* viewContainer;
#property (nonatomic, strong) IBOutlet UILabel* lblLevel;
#property (nonatomic, strong) IBOutlet UILabel* lblRanking;
#property (weak, nonatomic) IBOutlet DYRateView *viewRate;
- (void)setLevel:(NSNumber*)level andRanking:(NSNumber*)ranking;
- (void)setupUI;
#end
.m File
#import "LevelAndRankDetails.h"
#import "AppDelegate.h"
#import "Constants.h"
#implementation LevelAndRankDetails
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]){
[self commonSetup];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self commonSetup];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
}
- (void)viewFromNibForClass {
[[NSBundle mainBundle] loadNibNamed:[[self class] description] owner:self options:nil];
[self addSubview:self.contentView];
self.contentView.frame = self.bounds;
}
- (void)commonSetup {
[self viewFromNibForClass];
//For View's Corner Radius
self.contentView.layer.cornerRadius = 12;
self.contentView.layer.masksToBounds = YES;
self.contentView.backgroundColor = kDefaultBackgroundGreyColor;
self.viewContainer.backgroundColor = kDefaultBackgroundGreyColor;//[UIColor clearColor];
self.backgroundColor = kDefaultBackgroundGreyColor;
//self.viewContainer.backgroundColor = UIColorFromRGB(0xBB9657);//[kLearnFromLightColor colorWithAlphaComponent:0.5];
self.viewRate.rate = 0;
self.viewRate.editable = NO;
self.viewRate.delegate = nil;
self.viewRate.alignment = RateViewAlignmentCenter;
self.viewRate.backgroundColor = [UIColor clearColor];
[self.viewRate setEmptyStarImage:[UIImage imageNamed:#"StarEmpty"]];
UIImage* imageFullStar = [[UIImage imageNamed:#"StarFull"] imageTintedWithColor:kSliderDarkYellowColor];
[self.viewRate setFullStarImage:imageFullStar];
self.lblLevel.textColor = [UIColor whiteColor];
self.lblRanking.textColor = [UIColor whiteColor];
//For Teacher label
}
- (void)setupUI {
self.contentView.layer.cornerRadius = 0;
self.contentView.layer.masksToBounds = YES;
self.contentView.backgroundColor = [UIColor clearColor];
self.viewContainer.backgroundColor = [UIColor clearColor];//[UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
}
- (void)setRanking:(CGFloat)ranking {
self.viewRate.rate = ranking;
}
- (void)setLevel:(NSNumber*)level {
self.lblLevel.text = [NSString stringWithFormat:#"Level : %#",level];
}
- (void)setLevel:(NSNumber*)level andRanking:(NSNumber*)ranking {
if (level.integerValue > 0) {
[self setLevel:level];
}
if (ranking.doubleValue > 0) {
CGFloat rankingConverted = ranking.floatValue;
[self setRanking:rankingConverted];
}
}
#end
And this is how you use it in your view controller
LevelAndRankDetails* toolTipCustomView = [[LevelAndRankDetails alloc] initWithFrame:CGRectMake(0, 0, 250, 66)];
toolTipCustomView.backgroundColor = [UIColor blackColor];
[toolTipCustomView setLevel:#(10) andRanking:#(3)];

How to get custom TableViewCell value on view controller without using button and set it after reload table in objective c

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];
}
}

How can I remove all label layers from cell

I am almost new to create a custom cell. I have a custom cell and created 6 labels on each row with a custom button(btnEdit). The custom button is droped from .xib. The btnEdit create a frame on two label and if that frame is clicked it call another function which is working fine.
The only issue I have is if I click on one of the btnEdit in the row I don't want it to be clicked in the other row unless it is removed OR if one is selected and the other clicked it remove the first and frame the other.
Here is my code that I hope it helps;
.H
#interface PositionTableCell : UITableViewCell {
IBOutlet UILabel *lblSymbol;
IBOutlet UILabel *lblSpl;
IBOutlet UILabel *lblLpl;
IBOutlet UILabel *lblrate;
IBOutlet UILabel *lblAmount;
IBOutlet UILabel *lblO;
}
#property (nonatomic, assign) BOOL isSelected;
#property (nonatomic, assign) BOOL isRowSelected;
#end
.M
- (IBAction)btnEdit:(id)sender
{
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(value1)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[lblLpl addGestureRecognizer:tapGestureRecognizer];
UITapGestureRecognizer *tapGestureRecognizer2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(value2)];
tapGestureRecognizer2.numberOfTapsRequired = 1;
[lblSpl addGestureRecognizer:tapGestureRecognizer2];
if (!isSelected){
lblLpl.layer.borderColor = lblSpl.layer.borderColor = [UIColor blueColor].CGColor;
lblLpl.layer.borderWidth = lblSpl.layer.borderWidth = 5.0;
lblLpl.userInteractionEnabled = lblSpl.userInteractionEnabled= YES;
isRowSelected = YES;
isSelected = YES;
}
else if (isSelected){
lblLpl.layer.borderColor = lblSpl.layer.borderColor = [UIColor clearColor].CGColor;
lblLpl.layer.borderWidth = lblSpl.layer.borderWidth = 0;
lblLpl.userInteractionEnabled = lblSpl.userInteractionEnabled= NO;
isRowSelected = NO;
isSelected = NO;
}
[tapGestureRecognizer release];
[tapGestureRecognizer2 release];
NSLog(#"CLICKED");
}
It can be solved by using keeping a reference of your previously selected cell.
Declare a variable in your .m file, like:
static PositionTableCell *previousCell = nil;
And modify your method like:
- (IBAction)btnEdit:(id)sender
{
if (previousCell != nil && previousCell != self)
{
for (id subLabel in [[previousCell contentView] subviews])
{
if ([subLabel isKindOfClass:[UILabel class]])
{
UILabel *tempLabel = (UILabel *)subLabel;
tempLabel.layer.borderColor = [UIColor clearColor].CGColor;
tempLabel.layer.borderWidth = 0;
tempLabel.userInteractionEnabled = NO;
isRowSelected = NO;
isSelected = NO;
}
}
}
// Other codes here
}

iOS 7 UITableView grouped style hide my cells

I have created an UITableView in my app programatically. I have a strange problem. I have never seen this and I think everything is alright. It seems like all the table goes down and I only can see the first row. I want to create the same UITableView grouped as the settings tableViews in iOS7
But the Image in iOS 6 it is strange too.. I have written a NSLog and the height is 132 = 3 items * 44 height cell.
Here it is the code.
static float x = 10.0;
static float y = 80.0;
static NSString *CategoryCellIdentifier = #"CategoryCell";
static float kHeightCell = 44.0;
#interface LKLHomeViewController ()
#property (nonatomic, strong) NSArray *itemsArray;
#property (nonatomic, strong) UITableView *categoryTableView;
#end
#implementation LKLHomeViewController
#synthesize itemsArray;
#synthesize categoryTableView;
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor grayColor]];
// Adding tableView to self.view
[self.view addSubview:self.categoryTableView];
}
#pragma mark - Custom getter
-(NSArray *)itemsArray
{
if(!itemsArray){
itemsArray = #[#"Near", #"Kind of" , #"More.."];
return itemsArray;
}
return itemsArray;
}
- (UITableView *)categoryTableView
{
//custom init of the tableview
if (!categoryTableView) {
CGFloat height = kHeightCell * [self.itemsArray count];
CGFloat width = self.view.frame.size.width - (x*2);
CGRect tableFrame = CGRectMake(x, y, width, height);
// regular table view
categoryTableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped];
categoryTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
categoryTableView.delegate = self;
categoryTableView.dataSource = self;
categoryTableView.backgroundColor = [UIColor whiteColor];
[categoryTableView setScrollEnabled:NO];
[[categoryTableView layer] setCornerRadius:5.0f];
return categoryTableView;
}
return categoryTableView;
}

Displaying a single string in a view programmatically on iOS

We have a window filled with little view squares (think of a Calculator).
For a specific view on the window we want display a single string in the view without using the Interface Builder to add the string.
We need to be able to change the string and have the view refresh.
How do we programmatically add a string to a view and show it?
Update:
Ok here is the code we have currently. Nothing special in the header file.
I suppose the real quandry is considering we can easily get the background color to change, why is it that our text is just not showing??
Both versions are in there, would be happy to get 'apples' or 'oranges' displaying.
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
bgString = #"orange";
UILabel* aLabel = [[UILabel alloc] init];
aLabel.text = #"apple";
self.textLabel = aLabel;
[aLabel release];
[self addSubview:textLabel];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
[[UIColor yellowColor] setFill];
UIRectFill(rect);
[self drawStringCenteredIn:rect];
}
- (void)drawStringCenteredIn:(CGRect)r {
//CGSize strSize = [bgString size];
CGPoint strOrigin;
strOrigin.x = r.origin.x; //+ (r.size.width - 10)/2;
strOrigin.y = r.origin.y; //+ (r.size.height - 10)/2;
//[bgString drawAtPoint:strOrigin withFont:[UIFont fontWithName:#"Helvetica" size:10]];
[textLabel drawTextInRect:r];
}
In your view controller's .h:
#interface MyViewController
{
UILabel* label;
}
#property (nonatomic, retain) UILabel* label;
In your view controller's .m:
- (void)dealloc
{
[label release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel* aLabel = [[UILabel alloc] init];
aLabel.text = #"Initial Text";
self.label = aLabel;
[aLabel release];
[self.view addSubview:aLabel];
}
- (void)viewDidUnload
{
[self.label removeFromSuperview];
self.label = nil;
}
// Call this when you need to update the label
- (void)updateLabel
{
self.label.text = #"Some updated text";
}
Did that from memory but it should work.
Try this:
UILabel* aLabel = [[UILabel alloc] initWithFrame:[self bounds]];
If you are creating the label manually, you need to set it's frame manually too.
Frame itself is size and position inside parent view(superview).
In my example i've set the frame of label to occupy the entire view. If you need your custom size you can use:
UILabel* aLabel = [[UILabel alloc] initWithFrame:CGRectMake(x,y,width,height)];
Where (x,y) - position of the top left corner of your label.
How about creating a UILabel and adding it to the view?
If you subclass the UIView, you can draw your string in the view's drawRect. This allows great flexibility in modifying the text, its appearance, and its placement (you can even animate it around, spin, rotate, etc.)
Call setNeedsDisplay on the view after you change your NSString. Then do an drawAtPoint:withFont: on the NSString when the drawRect is called.

Resources