Custom MPVolumeView Thumb Image not vertically centered since iOS 5.1 - ios

I'm building an application that needs an MPVolumeView to control the volume. It worked perfectly before iOS 5.1 but since the 5.1 update the thumb image is no longer vertically centered. I tried a few things like changing imagine dimensions, resizing my views (and slider) but nothing seems to work, the thumb is just not vertically centered anymore. The only way i get a centered thumb is if i use the default iOS one.
I tried adding a UISlider to another view with the exact min, max and thumb image and that one is centered fine.
Here is the code for the MPVolumeView:
MPVolumeView *volumeView;
volumeView = [[[MPVolumeView alloc] initWithFrame:volumeViewHolder.bounds] autorelease];
[volumeViewHolder addSubview:volumeView];
UIView *volumeViewSlider;
for (UIView *view in [volumeView subviews])
{
if ([[[view class] description] isEqualToString:#"MPVolumeSlider"])
{
volumeViewSlider = view;
}
}
[(UISlider *)volumeViewSlider setThumbImage:sliderHandleIcon forState:UIControlStateNormal];
[(UISlider *)volumeViewSlider setMinimumTrackImage:leftTrackImage forState:UIControlStateNormal];
[(UISlider *)volumeViewSlider setMaximumTrackImage:rightTrackImage forState:UIControlStateNormal];
volumeViewHolder is just a UIView thats 153x33. I put the thumb in green in the screenshot.

Maybe a better solution:
User a bigger image with a transparent border on the bottom. Should be around 10px for Retina Displays.

the same problem i resolved in one project. Must be set color of left part and right part with alpha = 0 -it means transparent all slider without thumb (without moovable part of it). After we must create custom view for line of slider, without thumb. In this view any colored part may be shifted as you want, upper or below, left or right. It obtained using the defined y for your ocassion:
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(x,y,width, height)];
And add the slider to this line as subview. Resulted view will be slider. For example:
UISlider *ourSlider = ...;
//initialise UISlider
ourSlider.minimumTrackTintColor = [UIColor colorWithRed:0 green:122.0f/255.0f blue:1 alpha:0];
ourSlider.minimumTrackTintColor = [UIColor colorWithRed:0 green:122.0f/255.0f blue:1 alpha:0];
UIView *lineOfSliderWithoutThumb = ... ;
// creation it
[lineOfSliderWithoutThumb addSubview:ourSlider];
//after this lineOfSliderWithoutThumb is the our custom uislider.
Note: colors there are used as default slider colors of left and right sides of UISlider.

Related

UIButton background image used for animation not aligned across devices

I have a UIButton backgroundImage that I use to display a weather condition image when the loading is complete. I also create a UIImageView that replaces the UIButton to animate a series of images as a progress indicator.
My question: How can fix this animated UIImageView x-axis misalignment across multiple screen sizes?
Here's what the sequence looks like on 4.7" iPhone, the red box indicates the image I'm talking about:
First, the UIImageView animating as a progress indicator (imagine it spinning, alignment is correct)
Second, the download complete, the progress indicator replaced by a UIButton with a backgroundImage:
Third, the UIImageView animating on 4" iPhone (note misalignment on x-axis):
Fourth, the download complete, UIButton replaces it, aligned correctly:
Here's how the UIImageView *progressIndicator is configured.
Note that conditionButton is the UIButton with backgroundImage of the weather condition:
self.progressIndicator = [[UIImageView alloc] initWithFrame:self.conditionButton.frame];
self.progressIndicator.contentMode = UIViewContentModeCenter;
self.progressIndicator.animationImages = #[...long series of images...];
self.progressIndicator.animationDuration = 0.5f;
[self.conditionButton setBackgroundImage:[UIImage imageNamed:#"empty.png"] forState:UIControlStateNormal];
[self.progressIndicator startAnimating];
[self.view addSubview:self.progressIndicator];
I'm pretty sure the issue is with
self.progressIndicator = [[UIImageView alloc] initWithFrame:self.conditionButton.frame];
But I'm not sure how to resolve this.
The same problem occurs when I switch to 5.5" iPhone. I have no Auto Layout warnings, and the constraints that apply to the conditionButton are:
Align Center X to superview
Width = 94
Height = 94
Bottom and Top space to nearest neighbor = default
Any help would be greatly appreciated!

If I add a background color to a UIButton, how do I inset it so the background is smaller?

If I have a UIButton and give it a red background, and the background size is a little too small or too big for my liking (but the tap target size is perfect), is there any way to change the size of them?
Basically the equivalent of adding padding in CSS so that it either takes up more area or less? Purely an aesthetic change.
Say with the background color applied to the button it visually takes up a 100px * 30px area. I want it to be 90px * 25px. Is this possible?
One way to do this, is to set the color of a sublayer of the button rather than the background color of the button itself.
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *sub = [CALayer new];
sub.frame = CGRectInset(self.topButton.bounds, 5, 2.5); // this will make the layer 90x25 for a button that is 100x30
sub.backgroundColor = [UIColor redColor].CGColor;
[self.topButton.layer addSublayer:sub];
}

IOS Button border thickness lssue,why?

UIButton top border appears thicker than the following ,but sometimes correct ,why?
code:
UIImage * sanImage = [UIimage imageNamed:#"product_bt1_normal"];
[self.saveBtn setBackgroundImage:[sanImage
stretchableImageWithLeftCapWidth:sanImage.size.width/3
topCapHeight:sanImage.size.height/3] forState:UIControlStateNormal];
Are you trying to make a button? If so, perhaps use a UIButton instead? You can control the border with button.layer.borderWidth = 1.0f
If you're set on using an image, create a UIImageView, and modify the border thickness that way:
UIImageView *iv = [[UIImageView alloc] initWithImage:sanImage];
[iv.layer setBorderWidth:0.5f];
It could be because of off-pixel boundaries. Since you are using height/3.0f, your image is maybe not returning a well-behaved image.
Also, there is a new stretchable image method you should be using, resizableImageWithCapInsets:.
So try this code out:
[self.saveBtn setBackgroundImage:[sanImage resizableImageWithCapInsets:UIEdgeInsetsMake(3.0f, 3.0f, 3.0f, 3.0f)] forState:UIControlStateNormal];
You might need to mess with the values for the insets a bit, I don't know the dimensions of your button image.

Why is there a rough black edge when rounding corner of UIButton?

I'm adding a UIButton (with background image) to the navigation bar and setting rounded corners with a border. I'm getting a strange black outline on the corners:
Here's the code I'm using to create the button from viewDidLoad:
ProfileImageService *profileImageService = [ProfileImageService getService];
CGRect frame = CGRectMake(0, 0, 32, 32);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button setBackgroundImage:profileImageService.profileImage forState:UIControlStateNormal];
[button addTarget:self action:#selector(showMenu) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = button.frame.size.height / 2.0;
button.layer.masksToBounds = YES;
button.clipsToBounds = YES;
button.layer.borderWidth = 3;
button.layer.borderColor = [UIColor colorWithRed:0 green:0.67 blue:0.97 alpha:1].CGColor;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
How can I make the border smooth and get rid of the subtle black outline?
What you're seeing is your profile image (the person's face) bleeding through the edge. This is because the border is anti-aliased and so has small amounts of transparency through which the profile image can bleed.
Since you're clipping the profile image and the border together, there's nothing stopping the profile image from extending through the border. (i.e. clipsToBounds won't clip the content to the inside of the border; it clips everything to the outside of the border) You can prove this by using a bright red image: you'll see a bright red fringe.
If you can just make the profile image circular and the right size beforehand (either offline or in code) then you'll avoid this problem.
The other solutions I see are to either implement your own drawRect: method and do the drawing yourself or to create another sub-layer of the button to hold the image which is clipped in the same way, but without the border. (Either way, you probably need to make your own UIControl for this rather than using UIButton, as manipulating the button's layers could lead to weird behavior.)
Edit: Here are some other solutions, too: iOS: Rounded rectangle with border bleeds color

Scrolling UILabel like a marquee in a subview

I have a UILabel in the main view with text - "Very Very long text". The proper width to this would be 142, but i've shortened it to 55.
Basically I want to implement a marquee type scroll, so I wrote code to add it onto a subview and animate it within the bounds of that view.
CODE --
CGRect tempLblFrame = _lblLongText.frame;
UIView *lblView = [[UIView alloc] initWithFrame:tempLblFrame];
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];
//SetClipToBounds so that if label moves out of bounds of its superview, it wont be displayed
[lblView setClipsToBounds:YES];
[lblView setBackgroundColor:[UIColor cyanColor]];
[self.view addSubview:lblView];
After this I get this output on the simulator -->
The problem occurs when i try the Animation with this code -
tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width;
[UIView animateWithDuration:2.0 delay:1.0 options:UIViewAnimationOptionCurveLinear
animations:^{
[_lblLongText setFrame:tempLblFrame];
}
completion:^(BOOL finished) {
NSLog(#"completed");
}];
I was hoping I would see the entire "Very Very long text", rather only "Very..." scrolls from left to right.
To solve this I added one line of code --
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
tempLblFrame.size.width = _lblLongText.intrinsicContentSize.width; //THIS LINE WAS ADDED
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];
I thought the full text will be set inside the newly added UIView and it would scroll properly. But running in the simulator gave me this --
And again, only "Very..." was scrolling from left to right.
What am I doing wrong? Please help!!
EDIT
Apparently the culprit was AutoLayout.
I have no clue why, but once I unchecked "Use Autolayout" for the view
in the XIB, everything started working as expected. Setting
tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width; was
working properly and so was the scroll.
Any explanation on this!!?
This question is possibly Duplicate of.
Although there is nice code snippet written by Charles Powell for MarqueeLabel,
also take a look at This link.
I hope this will help you and will save your time by giving a desired output.
Make the UILabel the width (or longer) of the text and the UIView the scroll area you want to see. Then set the UIView's clipToBounds to YES (which you are doing). Then when you animate left to right you will only see the the text the width of the UIView, since it is cutting any extra subviews. Just make sure you scroll the entire length of the UILabel.
Right now you are setting the view and label's height and width to the same thing. This is why you are getting clipped text, not a clipped label.
You add In your view scrollview and add this label in your scroll view .Use this code
scroll.contentSize =CGSizeMake(100 *[clubArray count],20);
NSString *bname;
bname=#"";
for(int i = 0; i < [clubArray count]; i++)
{
bname = [NSString stringWithFormat:#"%# %# ,",bname,[[clubArray objectAtIndex:i] objectForKey:#"bottle_name"]];
[bname retain];
}
UILabel *lbl1 = [[UILabel alloc] init];
[lbl1 setFrame:CGRectMake(0,5,[clubArray count]*100,20)];
lbl1.backgroundColor=[UIColor clearColor];
lbl1.textColor=[UIColor whiteColor];
lbl1.userInteractionEnabled=YES;
[scroll addSubview:lbl1];
lbl1.text= bname;
This is implemented code.Thanks
Apparently the culprit was AutoLayout.
I have no clue why, but once I unchecked "Use Autolayout" for the view in the XIB, everything started working as expected. Setting tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width; was working properly and so was the scroll.
Still, a better explanation for this would surely help!!
EDIT: Solution with AutoLayout -
//Make UIView for Label to sit in
CGRect tempLblFrame = _lblLongText.frame;
UIView *lblView = [[UIView alloc] initWithFrame:tempLblFrame];
//#CHANGE 1 Removing all constraints
[_lblLongText removeConstraints:_lblLongText.constraints];
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
//Set Full length of Label so that complete text shows (else only truncated text will scroll)
tempLblFrame.size.width = _lblLongText.intrinsicContentSize.width;
//#CHANGE 2 setting fresh constraints using the frame which was manually set
[_lblLongText setTranslatesAutoresizingMaskIntoConstraints :YES];
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];

Resources