I have a subclass of UIView called InvitedView. It is instantiated in viewDidLoad like this:
ViewController.m
invitedView = [[InvitedView alloc] initWithFrame:CGRectMake(100, 244, 120, 80)];
invitedView.backgroundColor = [UIColor colorWithRed:156.0f/255.0f green:214.0f/255.0f blue:215.0f/255.0f alpha:0.9f];
[self.view addSubview:invitedView];
[invitedView setHidden:YES];
The class itself looks like this:
InvitedView.m
#import "InvitedView.h"
#import "AppDelegate.h"
#import "ViewController.h"
#class ViewController;
#interface InvitedView() {
UIButton *accept;
UIButton *decline;
UILabel *question;
UIView *gray;
ViewController *myViewController;
}
#end
#implementation InvitedView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
gray = [[UIView alloc] initWithFrame:frame];
NSString *holduser = [(AppDelegate*)[[UIApplication sharedApplication] delegate] invitedby];
[self addSubview:gray];
accept = [[UIButton alloc] init];
decline = [[UIButton alloc] init];
question = [[UILabel alloc] init];
question.text = [[NSString alloc] initWithFormat:#"You have been invited to a group game by %#", holduser];
question.numberOfLines = 0;
question.textAlignment = NSTextAlignmentCenter;
question.textColor = [UIColor colorWithRed:211.0f/255.0f green:243.0f/255.0f blue:219.0f/255.0f alpha:1.0f];
accept.backgroundColor = [UIColor clearColor];
accept.frame = CGRectMake(20, gray.frame.size.height / 2, (gray.frame.size.width / 2) - 10, (gray.frame.size.height / 2) - 20);
decline.backgroundColor = [UIColor clearColor];
decline.frame = CGRectMake((gray.frame.size.width / 2) + 10, (gray.frame.size.width / 2) - 20, (gray.frame.size.width / 2) - 20, (gray.frame.size.height / 2) - 20);
question.frame = CGRectMake(20, 20, gray.frame.size.width, (gray.frame.size.height / 2) - 20);
[question setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:18.0]];
[accept addTarget:myViewController action:#selector(acceptInvite) forControlEvents:UIControlEventTouchUpInside];
[decline addTarget:myViewController action:#selector(declineInvite) forControlEvents:UIControlEventTouchUpInside];
[gray addSubview:accept];
[gray addSubview:decline];
[gray addSubview:question];
}
return self;
}
#end
The method where the view is supposed to be shown is in the view controller showing the view. It ends up getting called, I can verify that the log messages happen all the way up until the setHidden function:
ViewController.m
- (void)doSomethingWithTheNewValueOfFlagForHid {
NSLog(#"issettingtheview******");
dispatch_async(dispatch_get_main_queue(), ^(void){
NSLog(#"issettingtheviewmu2******");
[invitedView setHidden:NO];
});
}
I would like to know why invitedView isn't being shown after [invitedView setHidden:NO].
It gets all the way to setHidden, and then nothing happens. I would appreciate any help, thanks in advance.
In ViewDidLoad, change line to
[invitedView setHidden:NO];
to make sure you can actually see the view (frame is ok, no view above ...)
You might also want to check Xcodes 3D View Debugging
The only reason that it wasn't showing up, is that invitedView was being instantiated inside an if statement that wasn't being executed. However - shallowThought's idea to switch setHidden to YES started me down a more productive debugging tract, leading to the discovery.
Related
I want a searchbar that has a button on the left of the text field, and on the right. Identical to the searchbar found on the current Alien Blue reddit app.
So far, the closest thing I have to achieving this is that I have been able to change the text of the "Cancel" button on the right side using this line of code.
[self.searchController.searchBar setValue:#"Hello" forKey:#"_cancelButtonText"];
But that doesn't really help since I want the right side to open up different search options, not cancel the search.
Help me ____, you're my only hope
Put the effect first
//RWSearchBar.h
#define BarFrame CGRectMake(100, 20, 200, 44)
#import <UIKit/UIKit.h>
#interface RWSearchBar : UISearchBar
#end
//RWSearchBar.m
#import "RWSearchBar.h"
#implementation RWSearchBar
- (void)layoutSubviews {
self.frame = BarFrame;
}
#end
//RWViewController.m
#import "ViewController.h"
#import "RWSearchBar.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
RWSearchBar *searchBar = [[RWSearchBar alloc] init];
[self.view addSubview:searchBar];
CGRect aFrame = BarFrame;
UIButton *leftBtn = [[UIButton alloc] initWithFrame:CGRectMake(aFrame.origin.x - 60, aFrame.origin.y, 60, 44)];
leftBtn.backgroundColor = [UIColor blueColor];
UIButton *rightBtn = [[UIButton alloc] initWithFrame:CGRectMake(aFrame.origin.x + aFrame.size.width, aFrame.origin.y, 60, 44)];
rightBtn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:leftBtn];
[self.view addSubview:rightBtn];
}
You can custom more visual effect by yourself.
I have a GameOver UIView that I call from inside my main UIViewController. It is just a 'popover' window that has the text game over, the score, and some blur effects to blur the main UIViewcontroller.
I try to pass an int to the UIView, but it doesn't accept it unless it is in the - (void)drawRect:(CGRect)rect method.
If I move the score label to drawRect method, the label is updated. But the blur effects go away.
What am I doing wrong?
MainViewController.m
#import "GameOverView.h"
#interface ViewController () {
GameOverView * gov;
}
- (void) showGameOver {
gov = [[GameOverView alloc] initWithFrame:self.view.bounds];
NSLog(#"Passing score of: %i", self.score);
gov.finalScore = self.score;
[self.view addSubview:gov];
}
GameOverView.h
#interface GameOverView : UIView {}
#property (nonatomic) int finalScore;
#end
GameOverView.M
#implementation GameOverView
- (id) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
//self.backgroundColor = [UIColor redColor];
NSLog(#"Score:%i", self.finalScore );
UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = super.bounds;
[super addSubview:visualEffectView];
UILabel * lblGameOver = [[UILabel alloc] initWithFrame:CGRectMake(0,0, frame.size.width, 200)];
lblGameOver.center = CGPointMake(frame.size.width/2, 100);
lblGameOver.text = [NSString stringWithFormat: #"GAME OVER %i", self.finalScore];
[self addSubview:lblGameOver];
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 200)];
button.center = CGPointMake(frame.size.width/2, 200);
[button setTitle:#"Start New Game" forState:UIControlStateNormal];
[button addTarget:self action:#selector(removeSelfFromSuperview) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
return self;
}
- (void) removeSelfFromSuperview{
[self removeFromSuperview];
}
You are using the finalScore property in the init method of the GameOverView class, but you are only setting its value after initializing it.
Change your initialization method to
- (id) initWithFrame:(CGRect)frame finalScore:(int)fs{
// use 'fs' instead of 'self.finalScore'
}
It should work.
I wonder how there isn't any problem with the view background color. You are initializing the view and adding it as subview like this:
gov = [[GameOverView alloc] initWithFrame:self.view.bounds];
gov.finalScore = self.score;
[self.view addSubview:gov];
This will give the view background color as black which is default color. So you don't find much difference if you use blur effect.
you need to give the color for the view during the initialization :
gov = [[GameOverView alloc] initWithFrame:self.view.bounds];
[gov setBackgroundColor:[UIColor yourColor]];
[self.view addSubview:gov];
If you are planning to keep the code in initWithFrame, you don't need to worry about setting the background color. If you keep the code in drawRect, then you must set the background color,else it will be black color.
When coming to setting the score label, it doesn't matter whether you put it in drawRect or initWithFrame method. Make sure you use drawRect method only if you really have to draw on the view,so that you can call it later by using setNeedsDisplay
I alloc a viewcontroller without init it, but everything works fine. The subviews in the viewcontroller work fine.
Here is the code.
self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[ViewController alloc]];
The code in ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
}
- (void)test
{
self.view.backgroundColor = [UIColor whiteColor];
CGRect frame = CGRectMake( 50, 100, 200, 200);
UIScrollView *scrollView= [[UIScrollView alloc] initWithFrame:frame];
[self.view addSubview:scrollView];
frame= CGRectMake( 0, 0, 500, 500);
UIImageView *myImageView= [[UIImageView alloc] initWithFrame:frame];
[scrollView addSubview:myImageView];
scrollView.contentSize = CGSizeMake(500,500);
scrollView.backgroundColor = [UIColor blackColor];
myImageView.backgroundColor = [UIColor yellowColor];
scrollView.contentOffset = CGPointMake(0, 0);
}
#end
Avi got it right in (his?) comment. It's dumb luck. This is like saying "I've been driving my car for 30,000 km without changing the oil and it's running fine. Why does everybody say you have to change your oil?"
Init does the setup for a class, and it's ancestor classes. It's fairly certain that there is some setup that isn't getting done that will cause problems in the future.
The proper way to create an object is with alloc/init. If you don't do that, "the result is undefined."
I'm trying to debug some code that has a exc_bad_access crash. It appears I have a zombie, but I can't figure out why the object is being deallocated. It is a Unity3D project, built for iOS. The code in question is in a .mm file, so ObjectiveC++.
So Instruments shows the function that is being deallocated, but I don't really understand what is happening. The Responsible Caller is a function called LoadVideo, which is wrapped in an 'extern "C"'. The code is below:
extern "C"
{
void LoadVideo()
{
// get the current UIViewController
UIViewController *viewController = UnityGetGLViewController();
// create the videLoader object
VideoLoaderUIObject * vidLoader = [VideoLoaderUIObject new];
// start up our loading screen
gSavingVideoAlert = [[CustomIOS7AlertView alloc] init];
UIView* uiViewLoading = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 125)];
UILabel* loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 40)];
loadingLabel.numberOfLines = 2;
[loadingLabel setText:#"Loading videos\nPlease Wait..."];
[loadingLabel setTextAlignment:NSTextAlignmentCenter];
[loadingLabel setTextColor:[UIColor blackColor]];
[loadingLabel setBackgroundColor:[UIColor clearColor]];
[loadingLabel setFont:[UIFont fontWithName: #"Trebuchet MS" size: 14.0f]];
[uiViewLoading addSubview:loadingLabel];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
// Adjust the indicator so it is up a few pixels from the bottom of the alert
indicator.center = CGPointMake(uiViewLoading.bounds.size.width / 2, uiViewLoading.bounds.size.height - 50);
[indicator startAnimating];
[uiViewLoading addSubview:indicator];
[gSavingVideoAlert setContainerView:uiViewLoading];
[gSavingVideoAlert show];
// open the media gallery
[vidLoader startMediaBrowserFromViewController: viewController usingDelegate: vidLoader];
#ifdef DEBUG_LOGS
NSLog(#"video path %#", [vidLoader VideoPath]);
#endif
}
}
The problem seems to be at this line:
[vidLoader startMediaBrowserFromViewController: viewController usingDelegate: vidLoader];
The vidLoader object is from a VideoLoaderUIObject class, defined as:
#interface VideoLoaderUIObject : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
#private
bool mIsUsingCam;
NSMutableArray* mAssets;
NSMutableArray *mVidIPod;
NSMutableArray *mVidItems;
std::vector<UIInterfaceOrientation> mVidOrientations;
MyCustomViewController* mScrollViewController;
}
The output from Instruments is below:
What's stopping the vidLoader object being retained?
I have next issue:
this code worked well:
//UITableViewController class
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 80)];
[v setBackgroundColor:[UIColor redColor]];
self.tableView.tableHeaderView = v;
}
Result:
But next code is not worked:
// TopViewController class
#interface TopViewController : UIViewController
#end
// UITableViewController class
#property (strong) TopViewController *topBar;
#synthesize topBar;
- (void)viewDidLoad
{
[super viewDidLoad];
topBar = [[TopViewController alloc] init];
topBar.view.frame = CGRectMake(0, 50, 320, 80);
[topBar.view setBackgroundColor:[UIColor greenColor]];
self.tableView.tableHeaderView = topBar.view;
}
Result - just white space
But when i do this:
topBar.view.frame = CGRectMake(0, 50, 320, 400); // change height to 400
I've got next result:
Can some one explain this strange behavior?