IOS/Objective-C: Subview of Subview not displaying - ios

I am trying to create a chart where a bar in the form of a UIView displays on top of a background UIView. I'd like both to display on top of the UIView for the whole screen. I have done this before successfully, but while I can get the first view to display, I somehow can't get my code to display the bar. Could it have something to do with setting the color? Or can anyone suggest why the second subview is not displaying.
My code:
//Make background box:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat graphWidth = screenWidth-40;
CGFloat graphHeight = 160;
CGRect graphBounds =CGRectMake(20, 200, graphWidth, graphHeight);
float tableStartY = graphBounds.origin.y;
UIView *graphBox = [[UIView alloc] initWithFrame:graphBounds];
graphBox.backgroundColor = [UIColor colorWithRed:200.0/255.0 green:200.0/255.0 blue:200.0/255.0 alpha:0.2]; graphBox.layer.borderWidth = 1;
graphBox.layer.borderColor = [UIColor blueColor].CGColor;
//Make Bar
CGFloat barWidth = 20;
CGFloat barHeight = 100;
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
UIView *barView = [[UIView alloc] initWithFrame:aBar];
barView.backgroundColor = [UIColor blueColor];
barView.layer.borderWidth = 1;
barView.layer.borderColor = [UIColor redColor].CGColor;
// [graphBox addSubview:barView];
[self.view addSubview: graphBox];
If I run the above code, it displays the graphBox. If I add the bar directly to the view as a subView instead of the graphBox, the bar displays. However, if I uncomment out the line shown and add the barView first to the graphBox and then add the graphBox to the view, the barView does not display.
Thanks in advance for any suggestions.

If I understand correctly what you need to do, you should replace
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
with
CGRect aBar = CGRectMake(20, 1, barWidth, barHeight);
[edit: and obviously uncomment the addSubview line]

Perhaps this is an accident in your posted code, but you have specifically commented out where the barView would be added to the screen.
// [graphBox addSubview:barView];
In addition, as another answer lists, your offset is incorrect if you are adding barView to graphBox. If you add it to self.view instead, your offset is correct.
So, you've got two choices, depending on the containment you desire in your view hierarchy:
CGRect aBar = CGRectMake(20, 1, barWidth, barHeight);
// ...
[graphBox addSubview:barView];
or
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
// ...
[self.view addSubview: graphBox];
[self.view addSubview:barView];
Note that in the second option, the order is important to get the barView to display over top of the graphBox as they will be siblings.

Related

UILabelView cropping when expanded, but renders fully when inspected in view hierarchy

Image 1 shows issue. label has flexible width & height constrains, also we adding fix width & height to expand with. in View hierarchy it shows fully expanded as expected, but issue in real view:
Image 2 shows fully expanded label in View hierarchy:
Lable code
self.textLabel = [[RAVerticallyAlignedLabel alloc] initWithFrame: self.bounds andVerticalTextAlignment: [self verticalTextAlignment]];
self.textLabel.backgroundColor = ClearColour;
self.textLabel.userInteractionEnabled = NO;
self.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.textLabel.numberOfLines = 0;
viewToTruncate = self.textLabel;
textWidth = MAX(MIN(screenSize.width - 20, [label.text sizeWithAttributes: #{NSFontAttributeName : label.font}].width + 10);
[UIView animateWithDuration: 0.3 animations: ^
{
self->containerView.frame = CGRectMake(xPos, top , MIN(textWidth, screenSize.width - 2 * RAPadding), newTextviewHeight);
// Container view is added inside scroll view
self->containerView.layer.shadowRadius = kRATruncationUtiltityShadowRadius;
self->containerView.layer.shadowOpacity = kRATruncationUtiltityShadowOpacity;
self->containerView.layer.shadowOffset = kRATruncationUtiltityShadowOffset;
self->containerView.layer.shadowPath = [UIBezierPath bezierPathWithRect: self->containerView.bounds].CGPath;
self->containerView.layer.masksToBounds = NO;
self->viewToExpand.frame = CGRectMake(0, 0, textWidth + componentContentWidth, self->containerView.height);
//viewToExpand is UILable, added inside container view
self->viewToExpand.layer.borderWidth = 1.0;
self->viewToExpand.layer.borderColor = borderColor.CGColor;
self->viewToExpand.layer.backgroundColor = backgroundColor.CGColor;
}];
Found issue fix, it size wasn't issue but "gradientMask" was playing up on expand as below:
CAGradientLayer *gradientMask = [CAGradientLayer layer];
gradientMask.frame = CGRectMake(0, 0, viewToTruncate.width, viewToTruncate.height);
gradientMask.colors = #[(id)WhiteColour.CGColor,(id)WhiteColour.CGColor, (id)ClearColour.CGColor];
gradientMask.locations = #[#0, #(locationOfFade), #1];
viewToTruncate.layer.mask = gradientMask;
removing mask on expand , it was rendering as expected.

Centering image with Title Label in Navigation Bar

I am adding custom title label and custom image to navigation bar. I can correctly add the title label in the position I want but I cannot center horizontally the image to that label. I am adding a screenshot and the code I use which can help.
-(void)addIconInNavBar
{
CGSize imageSize = CGSizeMake(lblHeight, lblHeight);
CGFloat marginX = (self.navigationController.navigationBar.frame.size.width) - (imageSize.width / 2);
CGFloat marginY = (self.navigationController.navigationBar.frame.size.height / 2) - (imageSize.height / 2);
imageView.frame = CGRectMake(marginX, marginY , imageSize.width, imageSize.height);
[self.navigationController.navigationBar addSubview:imageView];
}
Please update for centerX as
CGFloat marginX = (self.navigationController.navigationBar.frame.size.width - imageSize.width) / 2;
Or
CGFloat marginX = (self.navigationController.navigationBar.frame.size.width/2) - (imageSize.width / 2);
I think, the better solution is using custom view for the title of the navigation bar.
UIView* customViewWithImage = [self createCustomView];
self.navigationItem.titleView = customViewWithImage;
You can get attributes of the title from the title attributes property, also you can get this information from appearance.
use it like this,
Create your custom view and add label and image in your custom view and add this custom view as titleView
UIView *vw = [[UIView alloc] initWithFrame:yourFrame];
UILabel *lbl = [[UILabel alloc] initWithFrame:lblFrame];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:imgFrame];
[vw addSubView:lbl];
[vw addSubView:imgView];
self.navigationItem.titleView = vw;

draw a circle of rectangles in Xcode

I have tried this code to draw a circle of rectangle
incNumberDefault=0;
for (int i = 0; i < maxNumber; i++) {
incNumberDefault = incNumberDefault +5;
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(incNumberDefault, 100, 3, 15)];
myView.center = CGPointMake(130,130);
myView.transform = CGAffineTransformMakeRotation(DegreesToRadians(incNumberDefault));
myView.backgroundColor = [UIColor lightGrayColor];
[self.speedDisplay addSubview:myView];
}
the outputs seems close circle where as i need transparent or space in middle of circle.
You can set UIView cornerRadius to half of the UIView width or height like,
myView.layer.cornerRadius=myview.frame.size.width / 2; or
myView.layer.cornerRadius=myview.frame.size.height / 2
For that you have to give same width and height to your UIView.
Try this :
// initialize the view with same height and width for perfect circle.
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 15, 15)];
// round the corner of view with required radius.
myView.layer.cornerRadius = myView.frame.size.width/2; // height can also be used
// circle with space in middle.
myView.backgroundColor = [UIColor clearColor];
myView.layer.borderColor = [UIColor lightGrayColor].CGColor;
myView.layer.borderWidth = 2.0f;
[self.speedDisplay addSubview:myView];
Hope it will solve your problem.
Thank you for your answer but i want to develop a dashed circle in certain distance and i have tired this code :
incNumberDefault=0;
for (int i = 0; i < maxNumber; i++) {
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(100+60 * sin(incNumberDefault), 100+60*cos(incNumberDefault), 3, 15)];
//myView.transform = CGAffineTransformMakeRotation(DegreesToRadians(incNumberDefault));
myView.backgroundColor = [UIColor lightGrayColor];
[self.speedDisplay addSubview:myView];
incNumberDefault = incNumberDefault +9;
}
but it generate random rectangle in a circle.
I want it in sequence.
Thank you.

How do I use UIPageControl in my app?

I am making an app where I need some images can be scrolled through using a UIPageControl. Sadly, I don't know how to use a UIPageControl, or a UIScrollView either. A link to a YouTube video or Xcode documentation by Apple would be much appreciated!
Thanks in advance!!
here is a code which will help you
CGSize size = [[UIScreen mainScreen] bounds].size;
CGFloat frameX = size.width;
CGFloat frameY = size.height-30; //padding for UIpageControl
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(offsetX, offsetY, frameX, frameY)];
scrollView.pagingEnabled = YES;
scrollView.backgroundColor = [UIColor clearColor];
scrollView.contentSize = CGSizeMake(frameX, frameY);
[self.view addSubview: scrollView];
// let say you have array of image in imageArray
for(int i = 0; i < [imageArray]; i++)
{
UIImage *image = [UIImage imageNamed:[imageArray objectAtIndex:i]];
imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(frameX * i, 0.0, frameX, frameY);
[scrollView addSubview:imageView];
}
scrollView.contentSize = CGSizeMake(frameX*[imageArray count], frameY);
please declare the variables according to scope of use. i have declared all the variables locally so that might not get confuse and also add the UIPageControl at the bottom of your viewcontroller
Implement the delegate method of UIScrollView to the current Page indicator
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float width = scrollView.frame.size.width;
float xPos = scrollView.contentOffset.x+10;
//Calculate the page we are on based on x coordinate position and width of scroll view
pageControl.currentPage = (int)xPos/width;
}
where pageControl is UIPageControl added on bottom your viewcontroller
ScrollView:
ScrollView is used to display the more number views/Objects. We can display those views by horizontal or vertical scrolling.
You can handle zooming, panning, scrolling etc.
You can go through some of these tutorials
Are there any good UIScrollView Tutorials on the net?
https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/UIScrollView_pg/CreatingBasicScrollViews/CreatingBasicScrollViews.html
Example Code for Scrollview:
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.height)];
//This will create a scrollview of device screen frame
You can enable the scrolling by
scroll.scrollEnabled = YES;
Example for adding 3 views to scrollview
NSInteger numberOfViews = 3;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(xOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scroll addSubview:awesomeView];
[awesomeView release];
}
// 3 views added horizontally to the scrollview by using xOrigin.
The most important part in this for is to understand the xOrigin. This will place every UIView exactly where the previous UIView has stopped, in other words, each UIView will start at the end of the previous one.
Now we got the scrollview with 3 views added horrizontally.
Set the UIScrollView contentSize
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
The contentSize is just the sum of the widths of the three UIViews, if the width of each UIView is 320, and we have three UIViews, your contentSize width will be 920.
[self.view addSubview:scroll];
[scroll release];
//Add scrollview to viewcontroller
Page Control:
A Page control presents the user with a set of horizontal dots representing pages. The current page is presented as a white dot. The user can go from the current page to the next or to the previous page.
To enable paging you need to add
scroll.pagingEnabled = YES;
pageControl = [[UIPageControl alloc] init]; //SET a property of UIPageControl
pageControl.frame = CGRectMake(100,self.view.frame.size.height-100,self.view.frame.size.width-200,100);
pageControl.numberOfPages = 3; //as we added 3 diff views
pageControl.currentPage = 0;
Add delegate method of scrollview to implement the pagecontrol dots while scrolling
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x – pageWidth / 2 ) / pageWidth) + 1; //this provide you the page number
pageControl.currentPage = page;// this displays the white dot as current page
}
Now you can see pagecontrol for scrollview. Hope you understand. Refer this too
https://developer.apple.com/library/ios/documentation/uikit/reference/UIPageControl_Class/Reference/Reference.html
This is a very good tutorial by the Ray Wenderlich team on how to set up a paging scrollview: How To Use UIScrollView to Scroll and Zoom Content
Apple's documentation also has an example of how to implement a paging scroll view: PhotoScroller
My answer to this previous question may also be useful to you.

Show progress line over existing elements

Not sure if the title is very clear but I don't know the exact name for the thing I'm looking for. I have a gird that consists of UIButtons (basically a sequencer). I want a line similar to the vertical line in this image (between the 8th and 9th button of each row:
So basically when my grid is being played I want to indicate the progress. Any idea how I could do this? What kind of elements to use etc.
You can add a UIView that is very narrow, 1 or 1.5 pixels. Set the background color to white or a gradient. Add this view to the same subview as the buttons.
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(100.0, 0.0, 1.5, 320.0)];
lineView.backgroundColor = [UIColor whiteColor];
[parentView addSubview:lineView];
To show progress you'll need to know how much is left until completion. Take that value and divide by 320 to get the lineView height.
CGRect frame = CGRectMake(100.0, 0.0, 1.5, 0);
lineView.frame = frame; // 0% complete
frame = CGRectMake(100.0, 0.0, 1.5, 160.0);
lineView.frame = frame; // 50% complete
frame = CGRectMake(100.0, 0.0, 1.5, 320.0);
lineView.frame = frame; // 100% complete
That is the idea. Hope this help.
Update to vertical bar moving across the screen
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 1.5, 320.0)];
lineView.backgroundColor = [UIColor whiteColor];
[parentView addSubview:lineView];
As progress is made
- (void)progressWithValue(CGFloat)progress {
CGRect frame = lineView.frame;
frame.origin.x = progress; // Change x position
lineView.frame = frame;
}
You can use UISlider to show the progress of your events or activity(not so clear of your code) and customize it according to your needs.You can look at the UICatalog sample code by Apple to get to know-how of customizing a UISlider along with other elements or UISlider Tutorial

Resources