Hide UISlider track when behind transparent thumb image - xcode

I'm currently creating a custom UISlider in Xcode. I am setting the thumb Image, min Image, and max Image for the slider. Everything works great. The design calls for the thumb image to be transparent to the background of the view. This is where my problem comes in, you can see the two sides of the slider coming together in the middle of the thumb image. I don't want it to look like this. I want the slider bars to stop a the edge of the thumb image. Any ideas as to how I can accomplish this? Any and all suggestions are welcome. Thanks.
This is the Code I'm using so far.
UIImage *thumbImage = [UIImage imageNamed:#"thumb.png"];
UIImage *minImage = [UIImage imageNamed:#"min.png"];
UIImage *maxImage = [UIImage imageNamed:#"max.png"];
minImage = [minImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
maxImage = [maxImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
[_slider setMinimumTrackImage:minImage forState:UIControlStateNormal];
[_slider setMaximumTrackImage:maxImage forState:UIControlStateNormal];
[_slider setThumbImage:thumbImageforState:UIControlStateNormal];
I can't Post an image because I don't have enough reputation. I'll try to explain a little better. I have a Thumb Image that is a circle. The center of the circle is transparent and you can see right to the background image of my view. The track for the slider continues all the way to the center of the circle. I'd prefer if the track stopped at the outline of the circle. I hope that makes more sense.

I have not received any suggestions as to how to hide the slider track when it is behind the thumb image so I am posting my solution incase someone else has this problem. If anyone has a better way of doing this please let me know.
In order to have a transparent thumb image and not have the track connect in the center of it I had to set the slider track images to blank images and setup my own slider track image that is just going to be resized every time the value of the slider changes. Not only will I be changing the width of the custom slider track but I also will have to update the X position of the image every time I resize it so that it will connect with the end image of my slider track.
In my case I have a slider that is set to 0 and its Max is set to the Width of the slider. My custom slider track is only going to appear on the right side of the thumb image. So as you slide the thumb image to the right the bar shrinks and the left side is clear.
First I setup my Slider Thumb Image and Set the Slider Track to Blank Images.
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *thumbImage =[UIImage imageNamed:#"answerSlider.png"];
[_slider setMinimumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setMaximumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setThumbImage:thumbImage forState:UIControlStateNormal];
thumbImage = nil;
_slider.value = 0;
}
In the ViewWillApear I have a call to setup my custom SLider track that I will create.
- (void)viewDidAppear:(BOOL)animated{
[self updateSlideBarLength];
}
Inside updateSLideBarLength I Use the value of the slider to help determine the width of my slider track Image.
- (void)updateSlideBarLength{
// Get Position Of Slider
CGFloat sliderValue = _slider.value;
CGFloat thumbImageWidth = 58; // this is the width of my thumb image
CGFloat sliderControlWidth = 288.0f; // This is a constant number in my case
CGFloat sliderWidth = sliderControlWidth - thumbImageWidth - sliderValue;
CGFloat sliderBarHeight = 2.0f;
// Reset Width Of aFrame
CGFloat sliderEndY = _sliderEnd.frame.origin.y;
CGFloat sliderEndX = _sliderEnd.frame.origin.x;
CGFloat sliderBarY = sliderEndY + (_sliderEnd.frame.size.height / 2 - 1);
CGFloat sliderBarX = sliderEndX - sliderWidth + (_sliderEnd.frame.size.width/2);
CGRect aframe = CGRectMake(sliderBarX, sliderBarY, sliderWidth, sliderBarHeight);
if (_sliderBar == nil) {
NSLog(#"Slider Bar Doesnt Exist");
_sliderBar = [[UIImageView alloc] initWithFrame:aframe];
_sliderBar.image = [UIImage imageNamed:#"sliderBar.png"];
[self.view addSubview:_sliderBar];
[self.view bringSubviewToFront:_sliderBar];
}
_sliderBar.frame = aframe;
}
Lastly I make sure the updateSliderBarLength is called every time the slider value changes.
- (IBAction)sliderMoved:(id)sender {
[self updateSlideBarLength];
}
This works although I had to adjust the Max value of my slider so that the custom slider track image I created always lines up with the edge of the thumb Image. While sliding the thumb image as the value increased the more the slider track started to infringe on my thumb image. By increasing the slider value I was able to stop this from happening. Again, I'm not convinced this is the best way to do this but it works for me. Later when I have more Rep and can post Pictures I will edit this post to help everyone visualize what I am describing.

I did something similar to Sean Marraffa, although I found it easier to subclass UISlider and update the frames of my image views in thumbRectForBounds:trackRect:value using something like this:
var trackHeight: CGFloat = 2
override func thumbRectForBounds(bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect
{
let superValue = super.thumbRectForBounds(bounds, trackRect: rect, value: value)
let originY = (bounds.height-trackHeight)/2.0
minTrackImageView?.frame = CGRectMake(0, originY, superValue.minX, trackHeight)
maxTrackImageView?.frame = CGRectMake(superValue.maxX, originY, bounds.width-superValue.maxX, trackHeight)
return superValue
}
minTrackImageView and maxTrackImageView are image views I set up in viewDidLoad.

Related

Xcode 5, why isn't the image resizing?

Hello I am trying to resize a UIImage, but even though I'm not getting any errors it is not working.
hers the code of .h file
IBOutlet UIImageView *Fish;
heres the code of .m file
Fish.frame = CGRectMake(0, 0, 300, 293);
What am I doing wrong?
Thanks for any help
The image is probably not resizing because you are just resizing the image view. Make sure in your storyboard that you make the image view (Fish), have the move ScaleToFill. I can't do screenshot due to reputation ( sorry :( )
Alternately, if your goal is not to resize the image view but to resize the image it is holding, you can do this:
UIImage *image = Fish.image;
UIImage *image = YourImageView.image;
UIImage *tempImage = nil;
CGSize targetSize = CGSizeMake(80,60);
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectMake(0, 0, 0, 0);
thumbnailRect.origin = CGPointMake(0.0,0.0);
thumbnailRect.size.width = targetSize.width;
thumbnailRect.size.height = targetSize.height;
[image drawInRect:thumbnailRect];
tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
YourImageView.image = tempImage;
and you would set thumbnailRect to whatever size you want.
Hope this helps! Please search Nerdy Lime on the app store to find all of my apps! Thanks!
I bet your outlet is not hooked up. In your "viewDidLoad" method, try doing this:
if(Fish)
{
Fish.frame = CGRectMake(0, 0, 300, 293);
} else {
NSLog(#"Fish is null; why did I forget to connect the outlet in my storyboard or xib?");
}
And this isn't the best way to resize your UIImageView. If you're using regular springs & struts, you can grow an outlet by clicking the springs & struts to grow based on the superview's size, e.g.:
And if you're doing AutoLayout, there's a different thing you can do (basically pin your view to all four sides of the superview).
Here is how I do it:
1) select the outlet / object you want to add constraints to (in your case, it'll be the fish image view)
2) see the segmented control at the bottom of the Interface Builder window? Click on the second one and you'll see a popover view open up with a list of possible constraints to add.
3) In my example, I'm adding constraints in my ImageView to always be 10 pixels from each edge of the superview (note the four "10"s and solid red lines meaning I'm adding four constraints).
AutoLayout is a pain to get accustomed to (and I'm still learning it myself), but I suspect that once one gets the hang of it, it'll be a powerful new tool especially as Apple brings in additional iOS screen sizes in the very near future.

IKImageBrowserView with background and wantsLayer

In my app I use IKImageBrowserView with background. If wantsLayer NO - all fine and IKImageBrowserView look like nice. But if I enabled wantsLayer (in parent view) the background in IKImageBrowserView is corrupt. (Sorry English is not my native language and I can't find the correct word).
If I understand correctly, problem in this fragment. But I can't see where.
NSRect visibleRect = [owner visibleRect];
NSRect bounds = [owner bounds];
CGImageRef image = NULL;
NSString *path = [[NSBundle mainBundle] pathForResource:[#"metal_background.tif" stringByDeletingPathExtension] ofType:[#"metal_background.tif" pathExtension]];
if (!path) {
return;
}
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:path], NULL);
if (!imageSource) {
return;
}
image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
if (!image) {
CFRelease(imageSource);
return;
}
float width = (float) CGImageGetWidth(image);
float height = (float) CGImageGetHeight(image);
//compute coordinates to fill the view
float left, top, right, bottom;
top = bounds.size.height - NSMaxY(visibleRect);
top = fmod(top, height);
top = height - top;
right = NSMaxX(visibleRect);
bottom = -height;
// tile the image and take in account the offset to 'emulate' a scrolling background
for (top = visibleRect.size.height-top; top>bottom; top -= height){
for(left=0; left<right; left+=width){
CGContextDrawImage(context, CGRectMake(left, top, width, height), image);
}
}
CFRelease(imageSource);
CFRelease(image);
Image with problem
Image without problem
Thanks
I tried using IKImageView a few weeks ago and ran in to a number if problems. It's a nice class but it doesn't seem to have been updated in a long time. I doesn't support retina screen and, as you point out goes crazy when you add a layer.
I wanted to do some custom drawing with CALayer over the top of an image. The first thing I tried was to add a layer to the image view, which gave me problems. The solution I went for want to add a custom NSView subview to the image view, add auto layout constraints so that it always the same size, then add a layer hosting view to the subview. This worked fine, so move your drawing code to a custom subview and it should work.
IKImageView
LayerHostingView (<--- add CALayer here)
I ran in to this distorted background image problem as well and it turned out to be that I had set up the CALayer for the background incorrectly. I suspect that you are misunderstanding the cause to be setting wantsLayer to false because when that is set the layer does not immediately redraw new layers that you set.
I reached this conclusion as if I set up the layer correctly, then set wantsLayer false immediately before setting a bad CALayer in the next line of code I see the correct, undistorted image first and only when I scroll (and it redraws) do I see the buggy effects in your screenshot. However if I set wantsLayer true at the same point in code I see the buggy graphics immediately when the browser loads, without having to redraw first.
You can move the wantsLayer false statement further down your code to find the line that's breaking it, it'll be where the layer is reset/updated somewhere.

How do i make a simple scrollview height = 80, width = 280, with images inside thats scrolls horizontally?

I need to make a simple scroll view in xcode with width of 280 and height of 80 and with images inside thats scrolls horizontally. i want to make this programmatically.
I assume you mean the UIScrollview, which has a guide written by apple found here:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html
A guide that I personally used was this one:
http://idevzilla.com/2010/09/16/uiscrollview-a-really-simple-tutorial/
I'll take you through the quick basics of adding the scrollview to your view and adding images to it.
I'm guessing you're new to Objective C, so I'll give you a quick guide. Firstly, you'll want to make a UIScrollView object. This is done by declaring the following:
UIScrollView *aScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake (0,0,320,250)];
You'll notice I set the frame. The first two numbers of CGRectMake give you the x and y origin of the point while the last two numbers are for how wide and tall you want your object to be.
Afterwards, you'll want to add images to it. You'll need a UIImageview.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 250)];
Note that I positioned the image at 0,0, giving it a height of a 250 and a width of 320. This ensures that it fills entire scrollview's initial view.
imageView.image = [UIImage imageNamed:#"foo.png"];
You'll attach an image to the imageView. But wait, there's more. So far you've created these objects but have not yet associated them with the view. So if we are in a ViewController class (you'll have to look up what that is), the ViewController contains a view. We can attach our objects to the view.
[aScrollView addSubview:imageView]; // Adds the image to the scrollview
[self.view addSubview:aScrollView]; // Adds the scrollview to the view.
If you want to add more images, you have to add them at different x origins. So our first added image was at 0,0. Our next added image should be at 320,0 (because the first image took up 320 pixels width).
UIImageView *secondImageView = [[UIImageView alloc] initWithFrame:CGRectMake(320, 0, 320, 250)];
secondImageView.image = [UIImage imageNamed:#"bar.png"];
[aScrollView addSubview:secondImageView];
There are a number of options for scrollview that you will want to explore. The ones I found useful were:
aScrollView.delegate = self; // For gesture callbacks
self.pagingEnabled = TRUE; // For one-at-a-time flick scrolling
self.showsHorizontalScrollIndicator = NO; // Cleaner look for some apps.
self.alwaysBounceHorizontal = TRUE; // Look it up.

UINavigationBar with image and default gradient background with iOS5

I'm attempting to use the new [UINavigationBar appearance] functionality in iOS5 to add a logo image to the UINavigationBars in my application. Primarily, I'd like to keep the default gradient, but center a transparent png in the NavBar. The logo image is roughly 120 pixels wide (240 pixels#2x).
I have first attempted this by setting the background image. The default behavior for setBackgroundImage:forBarMetrics: appears to be to tile the image, and all transparent parts show the default navbar background color, black. I can also set the background color via the appearance modifier, and get a flat color background, but I'd really like to get the original gradient behavior without maintaining a separate image resource for it. It also makes it easier to adjust in code, since I can adjust the tint there, rather than re-generating a new image if I decide to change it.
What I'm trying to use:
UIImage *logoImage = [UIImage imageNamed:#"logoImage"];
[[UINavigationBar appearance] setBackgroundImage:logoImage forBarMetrics:UIBarMetricsDefault];
You can do this two ways. If you want to always have the image in the navigation bar, then create an image view and set it as a subview of the navigation bar:
[self setLogoImageView:[[UIImageView alloc] init]];
[logoImageView setImage:[UIImage imageNamed:#"logo.png"]];
[logoImageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect navFrame = [[navController navigationBar] frame];
float imageViewHeight = navFrame.size.height - 9;
float x_pos = navFrame.origin.x + navFrame.size.width/2 - 111/2;
float y_pos = navFrame.size.height/2 - imageViewHeight/2.0;
CGRect logoFrame = CGRectMake(x_pos, y_pos, 111, imageViewHeight);
[logoImageView setFrame:logoFrame];
[[[self navigationController] navigationBar] addSubview:logoImageView];
If you only want to display the logo in a certain view, then set the view's navigation item:
[logoImageView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
[[self navigationItem] setTitleView:logoImageView];

UIImageview position change programmatically iPhone

I have create a iPhone quiz application where some questions have image and some is without image. For this I took a UItextfield for displaying question and a UIImageView for displaying question Image. But when question without image is appears then the question is displayed upper size of the xib and options are displayed lower side of the xib which is not good. I want to change the position of the image view and text field with correspond to question image. How can i change the position of uicontrol?. Plz help me. Thanks in advanced.
This is how you reposition / resize a UIView.
CGRect frame = myControl.frame;
frame.origin.x = newX;
frame.origin.y = newY;
frame.size.width = newWidth;
frame.size.height = newHeight;
myControl.frame = frame;

Resources