weird behavior of UISlider - iphone

I have an UISLider created programmatically inside UITableViewCell. the slider control works with audio file to show the progress .. this is the creation:
AudioSlider = [[UISlider alloc] initWithFrame:CGRectMake(78.0f, 28, 214, 10)];
AudioSlider.maximumValue = 100.0;
AudioSlider.minimumValue = 0.0;
[AudioSlider setTag:5];
[AudioSlider setValue:0.0];
[[self contentView] addSubview:AudioSlider];
the problem is that the slider does not show the start and end values of the progress correctly !! when I set value to 0.0 :
[AudioSlider setValue:0.0];
[AudioSlider setValue:100.0];
the photo explain the problem
I can't really find out the reason ...
Any idea ?
thanks in advance ..

You have omitted some important code from your question. It is clear from your screen shot that you have made the slider's thumb invisible, perhaps by using a transparent image.
Normally, the slider would cover those ends, so the user wouldn't see the wrongly-colored parts of the channel. But by making the thumb invisible, you've made the ends visible.
If this is really supposed to be a slider that the user can interact with, you need to replace the minimum track image and maximum track image of the slider, or you need to use a thumb image that hides the ends.
If this isn't supposed to be a control that the user can interact with, use UIProgressView instead of UISlider.

It's in a tableView so I'd suggest that you're probably not setting it when you think you are due to cell dequeueing.
Can you show the code that creates and configures the UITableViewCells.

Related

How do I use CGRectMake to size the background

Ok So I have this code, which allows me to put a background image in:
I would love to know how to size this, so on the iPhone 4 I can get a 320x480 size but make it nice with an image of 570.855.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background_stream-570x855.jpg"]];
I have tried this:
UIImageView *image = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"background_stream-570x855.jpg"]];
[self.view sendSubviewToBack:streamBG];
image.frame = CGRectMake(0, 0, 320, 480);
Which works, however the problem is it's behind the view, so I can't see it. I could make the view clear, but it has objects on it that need to be displayed.
Any help would be most apretiated
There are multiple options to put Views at desired location.
[self.view sendSubviewToBack:streamBG]; //Sends subview to last position i.e. at the last
[self.view bringSubviewToFront:streamBG] //Brings subview to first position i.e. at the first.
[self.view insertSubview:streamBG atIndex:yourDesiredIndex];//Put at desired index.
This is not answer to your question, though it may help you to set your imageview to desired location.
Hope it helps.
To answer part of your question about sizing. You need to use 2 different images for your app if you want the full resolution of the retina display (iPhone4) You should provide a 320x480 image (i.e. myImage.png) for older iPhones and one at twice the resolution, 640x960, for the iPhone 4. Use the exact same name for the high res version but add an "#2x" to the end (i.e. myImage#2x.png). In your code all you ever have to call is the base name (i.e. myImage.png) the app will choose the correct image based on the hardware its running on. That will get you the best experience on your app.
On the other part about the background view visibility, you could make the background color clear ([UIColor clearColor]) on the view that is blocking it. That would leave the content visible in that view but the view its self would be clear. Alternatively you could just insert the background at a specific index as #Jennis has suggested instead of forcing it to the back.

UISwitch - change from on/off to yes/no

does anyone know of a way I can change the text label for on and off to yes and no.
I did it with
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:0]).text = #"Yes";
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:1]).text = #"No";
However, with the release of iOS 4.2, this is no longer supported (this probably wasn't recommended by Apple anyway)
My client is insisting on yes/no switches. I'd appreciate any advice!
many thanks
Hurrah! From iOS 6, it's possible to specify an image to be used for the on / off states, respectively. So, this can be used to display a YES / NO image (or whatever image representing the text you would prefer to use instead of the previously limited ON / OFF).
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0"))
{
[mySwitch setOnImage: [UIImage imageNamed:#"UISwitch-Yes"]];
[mySwitch setOffImage:[UIImage imageNamed:#"UISwitch-No"]];
}
The images should be 77 px wide, 27 px high, and the text (one image for each state) should be horizontally centred within that 77 px width. I use transparent backgrounds for the text, so I can still make use of the tint for the background, which still works with this.
Of course, it would seem easier to just supply text, rather than having to use an image of text, but I'm certainly grateful for this new option, at least.
You need to implement your custom UISwitch for that. Or use one of already implemented :) (check this SO question and this post)
Vladimir answer is great, but in my humble opinion there is an even better implementation here: https://github.com/domesticcatsoftware/DCRoundSwitch.
Besides setting a custom text, it is easier to change the size and color of the UISwitch and you get a sharper result.
It is released under an MIT license. Have a look!
It turns out that you can create a custom UISwitch with the following items:
A UIScrollView
A UIButton
Two UILabels
A background image
A Boolean value
First you will need to add QuartzCore.framework to your project and #import <QuartzCore/QuartzCore.h> to your view controller.
Next add the UIScrollView to your view using Interface Builder. The ScrollView will be your custom UISwitch.
Next add the button and the two labels to your ScrollView. One label will be for "yes" the other for "no".
Add the image to the button and set its type to custom. This is the image I use:
Position the labels over the blue and white area of the image. Adjust the ScrollView so it is just big enough to show the blue part of the image and the thumb nob.
Add the following line to viewDidLoad:
self.mySwitch.layer.cornerRadius = 13.5;
mySwitch is the name of the ScrollView and 13.5 is half the height of the ScrollView. The above statement changes the ScrollView to have rounded ends like the UISwitch.
To make the custom switch active you will need to tie the buttons "Touch Up Inside" event to an IBAction. Here is the code I use in the event handler:
-(IBAction)mySwitchButton:(id)sender {
self.myValue = !self.myValue;
CGPoint scrollPoint = CGPointMake((self.myValue)? 43.0: 0, 0.0);
[mySwitch setContentOffset:scrollPoint animated:YES];
}
Where myValue is the boolean variable that contains the state of your switch and 43.0 is the number of points you will have to move the image over to put the switch in the off position.
That is all there is to it!
From iOS 6, it's possible to specify an image to be used for the UISwitch on / off states, but NOT the text.
This will lead trouble when internationalization is required because translators
have to provide an image text for each language, not text only.
Moreover, the size of the UISwitch image is fixed, limiting the text length.
Because of the above reasons, I like the JSWilson's answer: simple and flexible.
To relieve developers of the need to manually add the required controls, I coded a custom CRDScrollSwitch class that you can find at my GitHub repository:
https://github.com/corerd/CRDScrollSwitch

How to make UISlider's "track" invisible?

I'm trying to emulate Apple's "Slide to Unlock" feature in my application. I get to this point (image below), but as you can see the UISlider's "track" is visible and is covering up my text. Is there a way to change an attribute programmatically that will make the "track" invisible?
Please let me know if you need any of my code.
Thanks in advance!
EDIT: If I change the slider's alpha to 0, it gets rid of my sliding button, so doing that won't work unless I'm doing it wrong. :)
here's an even easier way. No need to create images, just instantiate an empty UIImage class :P
UIImage *clearImage = [[UIImage alloc] init];
[self.slider setMinimumTrackImage:clearImage forState:UIControlStateNormal];
[self.slider setMaximumTrackImage:clearImage forState:UIControlStateNormal];
Actually I just figured it out. Here's what I did:
UIImage *sliderMinimum = [[UIImage imageNamed:#"clearTrack.png"] stretchableImageWithLeftCapWidth:4 topCapHeight:0];
[slider setMinimumTrackImage:sliderMinimum forState:UIControlStateNormal];
UIImage *sliderMaximum = [[UIImage imageNamed:#"clearTrack.png"] stretchableImageWithLeftCapWidth:4 topCapHeight:0];
[slider setMaximumTrackImage:sliderMaximum forState:UIControlStateNormal];
clearTrack.png is just a clear slider image I made.
Now I have this: yay!
There probably isn't a way to hide the track; the "slide to unlock" doesn't behave like a UISlider and is probably a custom control. You might be able to hack the slider control, maybe by setting opacity low (0 will make it hidden and it won't receive touches), but if you go that route you will probably have something break after an OS update. Apple doesn't bend over backwards for compatibility like Microsoft does.
The right way to do this is with a custom control. It may seem like more work than using a UISlider, but it's not if you compare it against all the time you have spent and/or will spend hacking a UISlider.
To do it: subclass UIControl. Write your own drawing code to make it look right (you can probably reuse some of whatever you are doing now). Then register for touch events to move the slider handle:
UIControlEventTouchDown: if it's on the handle, set a "moving" flag
UIControlEventTouchDragInside: if the moving flag is set, move the handle to the touch position; you can just update an instance variable, call setNeedsDisplay to draw it in the new position.
UIControlEventTouchUpInside: if moving flag is set, and handle is at end, unlock
If you want to mimic the real unlock handle, play around with it and see how it behaves. You might need to respond to the events differently (what happens if you drag outside the slider path). But you should be able to get the gist of it.
In Swift:
slider.setMinimumTrackImage(UIImage(), forState: .Normal)
slider.setMaximumTrackImage(UIImage(), forState: .Normal)
In answer to the stated question, you can set a transparent 1px png for the minimum and maximum track images.
Looks like just setting the tint color to clear does it...
[slider setMinimumTrackTintColor:[UIColor clearColor]];
[slider setMaximumTrackTintColor:[UIColor clearColor]];
Answer by #Arjay Waran is the best in my opinion.
Heres the Swift 3.0 Version of it.
slider.minimumTrackTintColor = UIColor.clear
slider.maximumTrackTintColor = UIColor.clear
Cheers
From Story Board:-
select clear color for Min Track and Max Track

setting image to button -> take up lots of memory ? what should i do then

basically im running my apps with instruments and found out that by just setting a background image to the UIButton, it takes up 6mb of data(which i do not want in case low-memory warnings). i read around and found out that since the button has been assigned the image, it retains it(and the memory).
How should i code it then?My current codes are as below. Btw im new to iPhone development so please tell me what to do.
btw this button would just bring me to another view. is there anyway to release the memory that was allocated to this image?
.m file
-(void)viewDidLoad{
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"MainScreen.png"]];
selectionScreen.backgroundColor = background;
[background release]
}
You mentioned in comment above that your .png is under 300k. That's perhaps a touch big, but you're actually not looking at the right thing. A png gets expanded to a native CGImage object. I usually figure a 32-bit image with alpha takes up width * height * 4 bytes of memory. That's pretty much guaranteed to be bigger than the PNG it gets expanded from, and in your case could be quite big indeed. Enough so that the docs recommend not instantiating UIImages bigger than 1024 x 1024.
Now, one solution could be that -initWithPatternImage can take a small piece of your background, and will tile it when it's drawn. So your first shot at solving this would be to provide that method as small an image as possible, and let it tile to bigger sizes.
Second thing, the retention. You're correctly releasing your UIColor object after setting it on the background. You WANT that object you set it on to retain it! In a world of infinite memory, you'd want that button to retain its background color until the viewcontroller it's on gets dealloc'ed. If it's still huge and you really have to get rid of it before backing out of the view controller (say when you push to a new UINavigationController view or something), you could try setting background to nil (or a system default color maybe) in -viewDidDisappear and re-building your background in -viewWillAppear.
Wheb viewWillDisappear, you can set backgroundColor as another color, and release the background color you made.
-(void)viewWillDisappear:(BOOL)animated
{
// release original backgroundColor
// default backgroundColor is nil by UIView class reference.
selectionScreen.backgroundColor = nil;
}
Hope this can help you.
Did you try using something like:
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:/frameOfChoice/];
[button setBackgroundImage:[UIImage imageNamed:#"MainScreen.png"] forControlState:UIControlStateNormal];
I'm not sure how this effects the memory usage tho.

Loading MPMoviePlayerViewController with transparent background?

i´ve added a MPMoviePlayerViewController instance and playing of a movie works great.
I´ve 3 buttons and want to load different videos in a UIView-container. That works, too.
But if i click on a button to load an other video, everytime the background is flickering black.
I´ve set the color to "clearColor":
player.moviePlayer.backgroundView.backgroundColor = [UIColor clearColor];
But that doesn´t help. Is there a way to load a video without a background - only the video-content?
Thanks for your time.
Not sure about the flickering issue. You said it flickers when you load another video -- Are you unintentionally layering multiple videos on top of each other? Make sure you remove the old one!
The black background likely is because your
MPMoviePlayerController's
scalingMode property is set to MPMovieScalingModeAspectFit (Apple's Documentation:
MPMoviePlayerController
scalingMode)
For issue #2, like you, I had expected setting the backgroundView's color to handle this, however it seems there is another view behind that which you also need to set the backgroundColor to clearColor. My hack for this was to simply iterate through the movie player's subviews and set their backgroundColor to clear.
Hack/"Solution" example using your variable name:
for(UIView* subV in player.moviePlayer.view.subviews) {
subV.backgroundColor = [UIColor clearColor];
}
You have to re-apply clearColor to the subviews any time you enter/exit fullscreen mode as well. I hope someone else has a better solution because this method seems pretty kludgy.
another option is to hide the video player and then show it when it is ready to display
caveat needs IO6>= i believe:
https://stackoverflow.com/a/19459855/401896