Adding GLKView via storyboard and programatically - uiview

I am adding a GLKView to a UIView within a UIViewController. Eventually I will split the code out to use a UIViewController and GLKViewController, but for now my hands are tied and need to use the UIViewController.
My issue is that when I add the GLKView to the UIVIew via the storyboard, everything works fine. When I try to add the GLKView programmatically it doesn't seem to get initialized quite right. It shows up grey.
The only difference in my implementation aside from using an IBOutlet is that I call the first and last lines in the code block below.
glview = [[GLKView alloc] init]; // Non storyboard
[glview setContext:context];
[glview setDelegate:self];
[glview setUserInteractionEnabled:YES];
[self.view addSubview:glview]; // Non storyboard
After the initialization I set up an AVCapture session. I set the frame on my GLKView in the controllers viewWillAppear function. Do you see any reason why my GLKView isn't getting initialized correctly?

The application is managing the drawing routine so I needed to disable the "enableSetNeedsDisplay" on my programmatically created GLKView. The following code fixed my issue. Take note of the the penultimate line.
glview = [[GLKView alloc] init];
[glview setContext:context];
[glview setDelegate:self];
[glview setUserInteractionEnabled:YES];
[glview setEnableSetNeedsDisplay:NO]; // HERE IS THE FIX
[self.view addSubview:glview];

Related

UIImageView automatically removing itself from self.view

tutorialImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Tap to Start.png"]];
tutorialImage.frame = CGRectMake(0, 0, 1024, 768);
[tutorialImage addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(blankMethod)]];
tutorialImage.userInteractionEnabled = YES; // i use this line and the previous line so that the user can't press any buttons behind the image
tutorialImage.alpha = 0;
[self.view addSubview:tutorialImage];
[self.view bringSubviewToFront:tutorialImage];
[UIView animateWithDuration:1.0f animations:^{
tutorialImage.alpha = 1;
} completion:^(BOOL finished) {
[self.view addSubview:tutorialImage]; // this line makes the image come back
}];
I know you probably won't be able to deduce the problem just from this code, but is there anything in that code that makes the tutorialImage auto remove itself from it's superview?
Anyway, during the UIView animation the image fades in for a bit like normal, then it disappears. If I add that last line of code there (the commented one), the UIView animation will make the image fade in and flash once halfway through. I just added this image and there is no code telling it to remove itself from superview.
Let me know if you have any ideas as to fixing the problem or showing you more code, I'll check frequently.
Also, I've tried restarting the simulator which didn't work, and the tutorial image is declared in the h file UIImageView *tutorialImage;. The console doesn't show any errors or anything when the problem occurs or anything.
Edit:
Ok, strange. I altered the declaration in the H file from UIImageView *tutorialImage; to #property (strong, nonatomic) UIImageView *tutorialImage; then used _tutorialImage fixed the problem. Is this something to do with the strong parameter? I'll mark who ever can explain what was going on as correct.
When you have a weak reference, ARC will dealloc the object once there are no more retains on it (when no object is pointing at the object with a strong pointer). When you changed the #property to strong, you are now telling ARC to keep the object around until the parent (your view controller) is dealloc'ed.

Radial gradient background programmatically in UIViewController

I researched a lot but I cannot find a proper solutions. I want to add a radial background to a UIViewController which fits to a iPhone 4 and iPhone 5 screen (view See attached screenshot). The background should be done programmatically because i have several Scrollview with a height more than view.bounds.
Does anybody know a solution?
You can follow two different ways to achieve this.
The simple way. If you have an image (you posted a screenshot) wrap it into an UIImageView.
Once done you can add it as a subview of your controller's view sending it to back like the following.
UIImageView* radialImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"radialBackground"]];
[radialImage setFrame:[[self view] bounds]];
[[self view] addSubview:radialImage];
[[self view] sendSubviewToBack:radialImage];
The not simple one. Create a custom UIView (named RadialBackgroundView for example) and override drawRect: method.
- (void)drawRect:(CGRect)rect
{
// Take a look to CGContextDrawRadialGradient to draw radial gradient
}
You can use it like a simple image.
RadialBackgroundView* radialView = [[RadialBackgroundView alloc] initWithFrame:[[self view] bounds]];
[[self view] addSubview:radialView];
[[self view] sendSubviewToBack:radialView];

Add overlay image on top of drawRect

I have a UIView subclass and I am drawing in the drawRect method.
How can I add an overlay image on top of the drawRect target layer?
I add the following in the initWithFrame method:
//add the image overlay
UIImageView *overlageImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"downloaderFront.png"]];
overlageImage.center = self.center;
[self.layer addSublayer:overlageImage.layer];
//replacing the above line with below line does not fix either
[self addSubview:overlageImage];
This image is not visible on top of the drawRect drawing.
The stuff with the layer is certainly wrong. Just do this:
UIImageView *overlageImage =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"downloaderFront.png"]];
[self addSubview:overlageImage];
You can play with the frame of overlageImage to get the position where you want it.
As to your actual question: put a breakpoint. I suspect you'll find that your code is never even running (because your view's initWithFrame is never called). That's just a guess - you didn't say anything about how this UIView subclass instance gets into the interface - but it's a common enough mistake, and one should always suspect the obvious first!

UIView: layoutSubviews vs initWithFrame

When subclassing UIView, I usually place all my initialisation and layout code in its init method. But I'm told that the layout code should be done by overriding layoutSuviews. There's a post on SO that explains when each method gets called, but I'd like to know how to use them in practice.
I currently put all my code in the init method, like this:
MyLongView.m
- (id)initWithHorizontalPlates:(int)theNumberOfPlates
{
self = [super initWithFrame:CGRectMake(0, 0, 768, 1024)];
if (self) {
// Initialization code
_numberOfPlates = theNumberOfPlates;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
[scrollView setContentSize:CGSizeMake(self.bounds.size.width* _numberOfPlates, self.bounds.size.height)];
[self addSubview:scrollView];
for(int i = 0; i < _numberOfPlates; i++){
UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:#"a1greatnorth_normal_%d.jpg", i+1]];
UIImageView *plateImage = [[UIImageView alloc] initWithImage:img];
[scrollView addSubview:plateImage];
plateImage.center = CGPointMake((plateImage.bounds.size.width/2) + plateImage.bounds.size.width*i, plateImage.bounds.size.height/2);
}
}
return self;
}
It's the usual tasks: setting up the view's frame, initialising an ivar, setting up a scrollview, initialising UIImages, placing them in UIImageViews, laying them out.
My question is: which of these should be done in init, and which of these should be done in layoutSubviews?
Your init should create all the objects, with the required data. Any frame you pass to them in init should ideally be their starting positions.
Then, within layoutSubviews:, you change the frames of all your elements to place them where they should go. No alloc'ing or init'ing should take place in layoutSubviews:, only the changing of their positions, sizes etc...
In case you're autoresizing works perfectly with just autoresizingFlags, or autolayout, you may just use init to setup the whole view.
But in general your should do layouting in layoutSubviews, since this will be called on every change of the views frame and in other situation, where layout is needed again. Sometimes you just don't know the final frame of a view within init, so you need to be flexible as mentioned, or use layoutSubviews, since you do the layout there after the final size has been set.
As mentioned by WDUK, all initialization code / object creation should be in your init method or anywhere, but not in layoutSubviews.

Shadow in separate view from UIImage for dynamic adjustments

I would like to obtain this effect (http://stackoverflow.com/questions/7023271/how-to-adjust-drop-shadow-dynamically-during-an-uiimageview-rotation) but from a more complex image than just a red square ! If the link ever gets broken, it's a about how to adjust drop shadow dynamically during an UIImageView rotation.
So I tried implementing something but I just can't get the shadow in a separate layer... Here is my code, very simple, but doesn't work:
// here is my code
- (void)viewDidLoad {
[super viewDidLoad];
testView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"handNoShadow.png"]];
testViewShadow = [[UIView alloc] initWithFrame:testView.frame];
testViewShadow.layer.shadowPath = [[testView layer] shadowPath];
testViewShadow.layer.shadowOpacity = 1.0;
testViewShadow.layer.shadowOffset = CGSizeMake(10, 10);
testViewShadow.layer.shadowRadius = 5.0;
[self.view addSubview:testViewShadow];
[self.view addSubview:testView];
}
PS: i did #import
I do get an image but no shadow... =(
Any lead, help, code, link... is welcome !
Thanks
possible cause:
your testViewShadow.clipToBounds property is set to YES (should be NO)
your testViewShadow do the drawing of the shadow correctly but another UIView is on top and mask it. Check your Z order. Either the order in Storyboard/Nib file (or the order you added the subviews programmatically). Last in the list (or last one added) is on top. For my app I had to put the UIView that need a shadow last so that no other view mask it.

Resources