How to customze UISlider to get stepps visible - ios

I want to customize my UISlider to be able to show steps like in photo attached (BTW this is a font size selector, native control from my iPhone settings). I able to set images for min and max but I can't show steps. I don't need 3rd party libraries to do this, I'm sure that it's possible to customize UISlider to have this.
Please help.
Thanks in advance.

You can add some subviews behind the slider to display the steps:
int numSteps = 5;
for(int i=0; i<numSteps; i++){
CGFloat x = i*CGRectGetWidth(slider.frame)/(numSteps-1);
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(x, CGRectGetMidY(slider.frame)-5, 1, 10)];
v.backgroundColor = [UIColor lightGrayColor];
[slider.superview insertSubView:v belowSubview:slider];
UILabel numberLabel = [[UILabel alloc] init];
numberLabel.text = [NSString stringWithFormat:#"%i",i];
numberLabel.font = [UIFont systemFontOfSize:13];
[numberLabel sizeToFit];
numberLabel.center = CGPointMake(x, CGRectGetMidY(slider.frame)+CGRectGetHeight(numberLabel.frame)/2+7);
[slider.superview insertSubView:numberLabel belowSubview:slider];
}

Related

iOS - addSubview without overlap

In a for loop, I'm trying to add Labels to a ScrollView based on a number given by the user. Here is the code in Objective-C:
NSInteger numberOfViews = [self.textfieldNumViews.text intValue];
for (int i = 0; i < numberOfViews ; i++){
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 300, 12)];
label.text = [NSString stringWithFormat:#"%d",i];
label.backgroundColor = [UIColor lightGrayColor];
[self.scrollviewViewContainer addSubview:label];
}
The problem is that the labels are overlapping each other inside the ScrollView, when I really want them to just display one after the other.
Image I understand that this is due to how addSubview behaves, placing views on top of other views, but is there any way I can prevent that? Or some other function I could use? I feel like this should be an easy task but I can't seem to figure it out. Is there something like a vertical layout property I can add to the ScrollView? Or add margins to the labels?
You need to set the y lower for each subview. Check the third line:
NSInteger numberOfViews = [self.textfieldNumViews.text intValue];
for (int i = 0; i < numberOfViews ; i++){
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0, (i*20), 300, 12];
label.text = [NSString stringWithFormat:#"%d",i];
label.backgroundColor = [UIColor lightGrayColor];
[self.scrollviewViewContainer addSubview:label];
}

iOS Calc X position to place elements on a View

I want to add a Label and an Image in titleView of my NavigationItem. I am adding UILabel and UIImageView to a UIView and setting it as titleView of the navigation Item. Things are being added, but I am not able to calculate the length of label and place image next to it.
My code is :-
// Title Name + Image
UIView *titView = [[UIView alloc] initWithFrame:self.navigationItem.titleView.bounds];
self.navigationItem.titleView = titView;
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(-10, -20, 150, 30)];
title.text = #"Bunny ";
[title setTextColor:[UIColor orangeColor]];
[titView addSubview:title];
float x2 = 30; //+ title.bounds.size.width;
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"return" ]];
img.frame = CGRectMake(x2, -20, img.bounds.size.width, 30);
[titView addSubview:img];
I am looking for some way to calc the width text and set accordingly the width of the label. Right now I have set the width of the label as 150. And secondly, calc the x position to place the image just next to the label.
Tried many ways, but nothing works as expected. How can I achieve this ? Can you he give some guidelines such that regardless of length of text of label, things works as expected and UIView gets placed in the center of navigation item.
Any help is highly appreciated. Thanks.
You can call
[title sizeToFit];
after setting its properties and it will size itself to match the contained string.
Set the imageViews x origin to
CGRectGetMaxX(title.frame) + desiredSpacing;
And it could help to subclass UIView to achieve the final results by overwriting layoutSubviews and placing your views there, since the titleView's frame can be adjusted by the navigationBar...basically like this:
#implementation TitleView{
UILabel *_titleLabel;
UIImageView *_img;
}
- (id)initWithTitle:(NSString *)title andImage:(UIImage *)image
{
self = [super init];
if (self) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = title;
[_titleLabel setTextColor:[UIColor orangeColor]];
[_titleLabel sizeToFit];
[self addSubview:_titleLabel];
_img = [[UIImageView alloc] initWithImage:image];
[self addSubview:_img];
}
return self;
}
- (void)layoutSubviews{
CGFloat spacingBetweenTextAndImage = 0;
CGFloat width = CGRectGetWidth(_titleLabel.frame)+CGRectGetWidth(_img.frame)+spacingBetweenTextAndImage;
CGFloat x = (CGRectGetWidth(self.bounds)-width)/2;
_titleLabel.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_titleLabel.bounds))/2, CGRectGetWidth(_titleLabel.bounds), CGRectGetHeight(_titleLabel.bounds));
x+=CGRectGetWidth(_titleLabel.bounds)+spacingBetweenTextAndImage;
_img.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_img.bounds))/2, CGRectGetWidth(_img.bounds), CGRectGetHeight(_img.bounds));
}
#end
use in your viewController:
UIView *titleView = [[TitleView alloc] initWithTitle:#"Bunny" andImage:[UIImage imageNamed:#"return" ]];
self.navigationItem.titleView = titleView;

Insert NSArray of strings into UILabel and count by 1.

How Would I insert an array of strings into UILabel, and have them load or count by 1?
I'm trying to load the following array into the UILabel:
self.array = [NSArray arrayWithObjects:#"Testing 1",#"Testing 2",#"Testing 3", nil];
Here I am using an UIScrollView that automatically changes from each slide to each slide:
for (int i=1; i<=3; i++) {
// create label
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,30)];
text.text = [NSString stringWithFormat:#"%#", self.array];
text.font=[UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
text.textColor = [UIColor darkGrayColor];
text.textAlignment =NSTextAlignmentCenter;
// create imageView
UIImageView *lblView = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width, 325, 280, 240)];
// set label
[lblView addSubview:text];
// apply tag to access in future
lblView.tag=i+1;
// add to scrollView
[scrMain addSubview:lblView];
}
I have an example of how to do it with UIImageView:
for (int i=1; i<=3; i++) {
// create image
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"sti%02i.png",i]];
// create imageView
UIImageView *imgV = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width + 23, 60, 280, 260)];
// set scale to fill
imgV.contentMode=UIViewContentModeScaleToFill;
// set image
[imgV setImage:image];
// apply tag to access in future
imgV.tag=i+1;
// add to scrollView
[scrMain addSubview:imgV];
}
The images are in my project and are numbered sti01, sti02, and so on... It then counts by one for each images and then loads them into the scrollview. I hope this helps!
The y-position of the label should be adjusted according to the index.
You can use the array count instead of a fixed '3'.
You don't need an UIImageView in between.
You can try this:
for (int i = 0; i < self.array.count; i++) {
// create label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, i*30, self.view.frame.size.width,30)];
label.text = [self.array objectAtIndex:i];
label.font = [UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
label.textColor = [UIColor darkGrayColor];
label.textAlignment = NSTextAlignmentCenter;
// add to scrollView
[scrMain addSubview:label];
}
If I'm understanding you correctly, you need to make the following change:
text.text = [NSString stringWithFormat:#"%#", [self.array objectAtIndex:i]];
This will pull out the ith object from your array of strings and set that as the text of your UILabel.
Why don't you loop through the array instead of trying to assign the text to the whole array like this:
for (int i=0; i<3; i++) {
// create label
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,30)];
text.text = [NSString stringWithFormat:#"%#", [self.array objectAtIndex:i]];
text.font=[UIFont fontWithName:#"HelveticaNeueLTStd-LtCn" size:15];
text.textColor = [UIColor darkGrayColor];
text.textAlignment =NSTextAlignmentCenter;
// create imageView
UIImageView *lblView = [[UIImageView alloc] initWithFrame:CGRectMake((i-1)*scrMain.frame.size.width, 325, 280, 240)];
// set label
[lblView addSubview:text];
// apply tag to access in future
lblView.tag=i+1;
// add to scrollView
[scrMain addSubview:lblView];
}
That way you're just pulling that one string out, assigning it as the UILabel's text, then adding it as a subview to the appropriate imageView.

UILabels have Faint Borders

I thought the default was a border width of 0.0. So I'm surprised I'm seeing boarders around my UILabels. I even tried using a CALayer to set the border to 0.0 and to set it to white, but I still see faint outlines. Here's my code.
-(UIView *)calendarDay:(int)d date:(NSDate *)date width:(float)w height:(float)h
{
//d is the day number in the month of the 28/293 calendar. It should display in bold in the upper, left.
//date is the date of that day. It should display in the upper, right.
//w is the width of the UIView in which to insert the labels.
//h is the height of the UIView in which to insert the labels.
//First create an outer view with a red background color.
UIView *frameView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, h)];
[frameView setBackgroundColor:[UIColor redColor]];
//Next decrease the width and height slightly to make a smaller view that fits inside the larger one.
w = w*0.98;
h = h*0.98;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM-dd "];
UILabel *dayNumber = [[UILabel alloc] init];
dayNumber.text = [NSString stringWithFormat:#"%2d",d];
dayNumber.font = [UIFont boldSystemFontOfSize:16];
dayNumber.frame = CGRectMake(0,0,w/2,h/5);
dayNumber.backgroundColor = [UIColor whiteColor];
UILabel *gregDate = [[UILabel alloc] init];
gregDate.text = [dateFormat stringFromDate:date];
gregDate.textAlignment = NSTextAlignmentRight;
gregDate.frame = CGRectMake(w/2,0,w/2,h/5);
gregDate.backgroundColor = [UIColor whiteColor];
Following three lines were an attempt to make the borders disappear. It made no difference.
CALayer *gregDateLayer = [gregDate layer];
[gregDateLayer setBorderColor:[[UIColor whiteColor] CGColor]];
[gregDateLayer setBorderWidth:0.0];
[gregDate setTextColor:[UIColor blackColor]];
CGRect dayRect = CGRectMake(0, 0, w, h);
UIView *dayToReturn = [[UIView alloc] initWithFrame:dayRect];
[dayToReturn setBackgroundColor:[UIColor whiteColor]];
dayNumber.center = CGPointMake(w/4 ,h/4);
gregDate.center = CGPointMake(w*3/4,h/4);
[dayToReturn addSubview:dayNumber];
[dayToReturn addSubview:gregDate];
[frameView addSubview:dayToReturn];
dayToReturn.center = frameView.center;
return frameView;
}
I think that what you are thinking is a border is actually the background color of the UILabel.
Set the background color of your UILabels to [UIColor clearColor].

Adding a badge icon to round rect button?

Is there a convenient way to make a button with a badge? Not on the icon... I want to do it within the app. A button or an image with a badge selected by the program. Or do I have to build a library of photoshop images?
You'll need to use resizableImageWithCapInsets to achieve this without a library of photoshop images. There are some great threads (here and here) that explain its use.
Here's an example I just made to give you an idea:
//Create a label (width/height not important at this stage)
UILabel *yourLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 1, 1)];
yourLabel.text = #"7+";
[yourLabel sizeToFit];
CGRect labelFrame = yourLabel.frame;
//Here we create a UIImage that is resizable, but will not resize the areas concerned with the cap insets you've defined
UIImage *badgeImage = [[UIImage imageNamed:#"badge.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(5, 5, 5, 5)];
UIImageView *badgeImageView = [[UIImageView alloc]initWithImage:badgeImage];
badgeImageView.contentMode = UIViewContentModeScaleToFill;
badgeImageView.backgroundColor = [UIColor clearColor];
labelFrame.size.width += 5; //This is the 'padding' on the right and left (added together)
//If your badge edges are completely circular then you don't want to change the height, but if they're not then go ahead in the same way with the width. If your badge has a static height, you'll need to make sure the font size doesn't exceed this height; better start off with a small font-size
badgeImageView.frame = labelFrame; //The badge is now the right width with padding taken into account
//Center the label on the badge image view
yourLabel.center = CGPointMake(badgeImageView.frame.size.width/2, badgeImageView.frame.size.height/2);
//Finally we add the label to the badge image view
[badgeImageView addSubview:yourLabel];
//Add your badge to the main view
[self.view addSubview:badgeImageView];
[badgeImageView release];
[yourLabel release];
UILabel *lbl_notification_count = [[UILabel alloc]initWithFrame:CGRectMake(5,0, 18, 18)];
lbl_notification_count.textColor = [UIColor whiteColor];
lbl_notification_count.textAlignment = NSTextAlignmentCenter;
lbl_notification_count.text = [NSString stringWithFormat:#"%d",appDel.NotificationBadge];
lbl_notification_count.adjustsFontSizeToFitWidth=YES;
lbl_notification_count.layer.borderWidth = 1;
lbl_notification_count.layer.cornerRadius = lbl_notification_count.layer.frame.size.height/2;
lbl_notification_count.layer.masksToBounds = YES;
lbl_notification_count.layer.borderColor =[[UIColor colorWithRed:241.0/255.0 green:84.0/255.0 blue:67.0/255.0 alpha:1.0] CGColor];
lbl_notification_count.backgroundColor = [UIColor colorWithRed:241.0/255.0 green:84.0/255.0 blue:67.0/255.0 alpha:1.0];
lbl_notification_count.font = CustomFontMediumWithSize(12);
if (appDel.NotificationBadge >= 1) {
[btnNotification addSubview:lbl_notification_count];
[lbl_notification_count setHidden:NO];
}else{
[lbl_notification_count setHidden:YES];
}

Resources