I'm working on a project that ask to do the following steps.
Displays a UIButton with an initial count of 0
Touching the UIButton first time increments the count
Touching the UIButton second time increment the count every 1 second
My code got stuck at step 3, if I touch the UIButton the second time, the count will keep incrementing by 1. I can never get into [self performSelector:#selector(doDelay:) withObject:button afterDelay:1.0].
How can I add a counter to count how many times the user has clicked the UIButton?
Here is the code I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
CGRect rect=[[UIScreen mainScreen] bounds];
UIButton *button=[[UIButton alloc] initWithFrame:rect];
button.backgroundColor=[UIColor redColor];
//Step (1)
[button setTitle:#"Count = 0" forState:UIControlStateNormal];
[self.window addSubview:button];
//Step (2)
[button addTarget:self action:#selector(doButton:) forControlEvents:UIControlEventTouchUpInside];
//Step (3)
[self performSelector:#selector(doDelay:) withObject:button afterDelay:1.0];
return YES;
}
-(void)doButton:(id)sender
{
static int count;
count++;
NSString *s = [NSString stringWithFormat:#"Count = %i", count];
UIButton *b = sender;
[b setTitle:s forState:UIControlStateNormal];
}
-(void)doDelay:(id)object
{
[self doButton:object];
[self performSelector:#selector(doDelay:) withObject:object afterDelay:1.0];
}
For multiple button actions you have to remove button target doButton and add other you wanna. For your case pass to doDelay method your count and add it to afterDelay:
Try this:
int count;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
CGRect rect=[[UIScreen mainScreen] bounds];
UIButton *button=[[UIButton alloc] initWithFrame:rect];
button.backgroundColor=[UIColor redColor];
//Step (1)
count = 0;
[self updateButton:button];
[self.window addSubview:button];
//Step (2) and (3)
[button addTarget:self action:#selector(doButton:) forControlEvents:UIControlEventTouchUpInside];
return YES;
}
-(void)updateButton:(UIButton *)button {
NSString *s = [NSString stringWithFormat:#"Count = %i", count];
[button setTitle:s forState:UIControlStateNormal];
}
-(void)doButton:(UIButton *)button
{
count++;
if(count == 1) {
//Step(2)
[self updateButton:button];
} else if(count == 2){
//Step (3)
[self performSelector:#selector(doDelay:) withObject:button afterDelay:1.0];
}
}
-(void)doDelay:(UIButton *)button
{
count++;
[self updateButton:button];
[self performSelector:#selector(doDelay:) withObject:button afterDelay:1.0];
}
Just Remove this line
[self performSelector:#selector(doDelay:) withObject:object afterDelay:1.0];
and Replace this two action in your code....
-(void)doButton:(id)sender
{
static int count;
count++;
NSString *s = [NSString stringWithFormat:#"Count = %i", count];
UIButton *b = sender;
[b setTitle:s forState:UIControlStateNormal];
if (count == 2) {
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self selector:#selector(doDelay:) userInfo:sender repeats:YES];
}
}
-(void)doDelay:(NSTimer *)timer
{
[self doButton:timer.userInfo];
}
Related
I am a new objective-c developer. The purpose of the app being developed is to switch between 3 graphs each displaying scientific data. When the user drags their finger on these graphs, the data for that point is displayed. Currently, to switch between these three graphs, the UIScreenEdgePanGestureRecognizer was used. However, since Apple has got rid of this feature in recent updates, I want to use segmented controls to switch between the three graphs. I have been able to get the segmented controls to appear, however, I have not been able to get them to actually get the graphs to switch. I have attached the relavant parts of the (ORIGINAL) viewcontroller.m below. How would I go about this? Thanks.
For reference, the names of the three graphs are ts, ph, and pv.
- (void)viewDidLoad
{
[super viewDidLoad];
/*
// Show/hide nav bar
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(doubleTap)];
[tap setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:tap];
*/
touchHasRegistered = NO;
allowQualityScrubbing = NO;
shouldFineTune = 0;
hasFineTuned = NO;
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.navigationController setNavigationBarHidden:YES];
[self.containerView addSubview:self.chartView];
[self.view insertSubview:self.secondContainerView
aboveSubview:self.containerView];
[self.view insertSubview:self.infoView
aboveSubview:self.secondContainerView];
[self.containerView bringSubviewToFront:self.infoButton];
[self.view setBackgroundColor:[UIColor whiteColor]];
[self.chartView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.containerView);
}];
[self.infoView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.containerView);
}];
if (self.secondContainerView.superview != nil && self.chartView.image != nil) {
[self.secondContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.containerView).with.offset(20.0);
make.top.equalTo(self.containerView).with.offset(20.0);
make.height.equalTo([NSNumber numberWithFloat:self.secondContainerView.frame.size.height]);
make.width.equalTo([NSNumber numberWithFloat:self.secondContainerView.frame.size.width]);
}];
}
[self.secondContainerView addSubview:self.displayView];
[self chooseNewFileWithChartType:self.chartView.chart.substanceType valueType:#"ts"];
UIScreenEdgePanGestureRecognizer *rightRecog = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
action:#selector(resetChart:)];
[rightRecog setEdges:UIRectEdgeRight];
[rightRecog setCancelsTouchesInView:YES];
[self.chartView addGestureRecognizer:rightRecog];
UIScreenEdgePanGestureRecognizer *leftRecog = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
action:#selector(resetChart:)];
[leftRecog setEdges:UIRectEdgeLeft];
[leftRecog setCancelsTouchesInView:YES];
[self.chartView addGestureRecognizer:leftRecog];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view addSubview:self.popupView];
[self.popupView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(#(self.popupView.frame.size.height));
make.width.equalTo(#(self.popupView.frame.size.width));
make.center.equalTo(self.view);
}];
/*
// Add Adjuster Views
NSSet *tags = [self tagsForAdjusterViews];
CGFloat height = self.displayView.containerViewHeight/self.displayView.numberOfRows;
for (id tag in tags) {
RUAAdjusterView *adjusterView = [[RUAAdjusterView alloc] initWithFrame:CGRectZero
tag:[(NSNumber *)tag integerValue]];
adjusterView.delegate = self;
[adjusterView setBackgroundColor:[UIColor clearColor]];
[self.secondContainerView addSubview:adjusterView];
[self.secondContainerView bringSubviewToFront:adjusterView];
[adjusterView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.secondContainerView);
make.right.equalTo(self.secondContainerView);
make.top.equalTo([NSNumber numberWithFloat:(height*([(NSNumber *)tag floatValue] - 1) + self.displayView.containerViewOriginY + 2.0f)]);
make.height.equalTo([NSNumber numberWithFloat:height - 4.0f]);
}];
}
*/
}
- (NSSet *)tagsForAdjusterViews
{
return [NSSet setWithObjects:#1, #2, #6, #7, nil];
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark - Lazy Init
- (LocationIndicatorImageView *)chartView
{
if (!_chartView) {
_chartView = (LocationIndicatorImageView *)[[LocationIndicatorImageView alloc] initWithFrame:self.containerView.frame
image:[UIImage imageNamed:#"Water_ts_chart.png"]
sender:self];
[_chartView setChart:[RUChart chartWithChartType:#"ts"]];
}
return _chartView;
}
-(UIView *)displayView
{
if (!_displayView) {
_displayView = [[DisplayView alloc] initWithFrame:self.secondContainerView.frame];
[_displayView setDataSource:self];
}
return _displayView;
}
-(UIView *)secondContainerView
{
if (!_secondContainerView) {
CGFloat height = 343.0f;
CGFloat width = 225.0f;
_secondContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
}
return _secondContainerView;
}
-(UIImageView *)infoView
{
if (!_infoView) {
_infoView = [[UIImageView alloc] initWithFrame:CGRectZero];
[_infoView setImage:[UIImage imageNamed:#"Legend.png"]];
[_infoView setHidden:YES];
[_infoView setUserInteractionEnabled:NO];
[_infoView setBackgroundColor:[UIColor whiteColor]];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(30, 30, 310, 310)];
UITapGestureRecognizer *ytTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(showYoutubeVideo)];
[ytTap setNumberOfTapsRequired:1];
[container setUserInteractionEnabled:YES];
[container addGestureRecognizer:ytTap];
[_infoView addSubview:container];
UIImageView *youtube = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
[youtube setImage:[UIImage imageNamed:#"youtube.png"]];
UITextView *textView1 = [[UITextView alloc] initWithFrame:CGRectMake(youtube.frame.origin.x + youtube.frame.size.width,
youtube.frame.origin.y,
250,
youtube.frame.size.height/2.0)];
UITextView *textView2 = [[UITextView alloc] initWithFrame:CGRectMake(youtube.frame.origin.x + youtube.frame.size.width,
youtube.frame.origin.y + youtube.frame.size.height/2.0,
250,
youtube.frame.size.height/2.0)];
UIFont *font = [UIFont fontWithName:#"HelveticaNeue-Light" size:16.0];
[textView1 setText:#"Learn about Thermodynamic"];
[textView1 setFont:font];
[textView1 setTextContainerInset:UIEdgeInsetsMake(11.0, 4.0, 4.0, 0.0)];
[textView1 setUserInteractionEnabled:NO];
[textView2 setText:#"Properties of Water"];
[textView2 setFont:font];
[textView2 setTextContainerInset:UIEdgeInsetsMake(0.0, 4.0, 0.0, 0.0)];
[textView2 setUserInteractionEnabled:NO];
[container addSubview:youtube];
[container addSubview:textView1];
[container addSubview:textView2];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissInfo)];
[tap setNumberOfTapsRequired:1];
[_infoView addGestureRecognizer:tap];
}
return _infoView;
}
- (void)showYoutubeVideo
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.youtube.com/watch?v=rJR-6OEw09k"]
options:#{}
completionHandler:nil];
}
- (H2O_Wagner_Pruss *)wagPruss
{
if (!_wagPruss) {
_wagPruss = [[H2O_Wagner_Pruss alloc] initEOS];
}
return _wagPruss;
}
- (NSArray *)superheatedValues
{
if (!_superheatedValues) {
_superheatedValues = [[NSArray alloc] init];
}
return _superheatedValues;
}
- (NSArray *)superheatedKeys
{
if (!_superheatedKeys) {
_superheatedKeys = [[NSArray alloc] init];
}
return _superheatedKeys;
}
- (NSArray *)chartValueTypes
{
if (!_chartValueTypes) {
_chartValueTypes = [NSArray arrayWithObjects:#"ts",#"ph",#"pv", nil];
}
return _chartValueTypes;
}
- (RUAPopupView *)popupView
{
if (!_popupView) {
_popupView = [[RUAPopupView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 160.0f) text:#"t-s"];
}
return _popupView;
}
- (RUASpaceController *)spaceController
{
if (!_spaceController) {
_spaceController = [[RUASpaceController alloc] init];
// NOTE: Seems like (10/8.0 and 10/9.0) and 20/30.0 felt best of ones I tried. Could use some refining.
_spaceController.numPoints = 10;
_spaceController.maxDiff = 7.0;
}
return _spaceController;
}
#pragma mark - Gesture Selectors
- (IBAction)displayInfo:(id)sender {
[self.infoView setHidden:NO];
[self.infoView setUserInteractionEnabled:YES];
}
-(void)dismissInfo
{
[self.infoView setHidden:YES];
[self.infoView setUserInteractionEnabled:NO];
}
-(void)doubleTap
{
[self.popupView showHideAnimated:YES];
/*
if (self.navigationController.isNavigationBarHidden) {
[self.navigationController setNavigationBarHidden:NO animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
} else {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
*/
}
- (void)resetChart:(UIScreenEdgePanGestureRecognizer *)recog
{
[self.popupView.layer removeAllAnimations];
if (recog.state == UIGestureRecognizerStateEnded) {
NSInteger index = [self.chartValueTypes indexOfObject:self.chartView.chart.valueType];
NSLog(#"%#, %#", self.chartValueTypes[((index+1)+3)%3], self.chartValueTypes[((index-1)+3)%3]);
NSString *type;
if (recog.edges == UIRectEdgeRight) {
type = self.chartValueTypes[((index+1)+3)%3];
} else if (recog.edges == UIRectEdgeLeft) {
type = self.chartValueTypes[((index-1)+3)%3];
}
NSString *letter1 = [type substringToIndex:1];
NSString *letter2 = [type substringFromIndex:1];
NSString *displayName = [NSString stringWithFormat:#"%#-%#",letter1.uppercaseString,letter2];
self.popupView.text = displayName;
[self.chartView resetImage:[UIImage imageNamed:[NSString stringWithFormat:#"Water_%#_chart.png",type]]];
self.chartView.chart = [RUChart chartWithChartType:type];
[self inspectInfoButtonWithChartValueType:type];
[self chooseNewFileWithChartType:self.chartView.chart.substanceType valueType:type];
[self.secondContainerView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.containerView).with.offset(20.0);
make.height.equalTo([NSNumber numberWithFloat:self.secondContainerView.frame.size.height]);
make.width.equalTo([NSNumber numberWithFloat:self.secondContainerView.frame.size.width]);
}];
if (self.chartView.chart.displayPosition == RUChartDisplayPositionLeft) {
[self.secondContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.containerView).with.offset(20.0);
}];
} else if (self.chartView.chart.displayPosition == RUChartDisplayPositionRight) {
[self.secondContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.containerView).with.offset(-20.0);
}];
}
[self.popupView showHideAnimated:YES];
if (touchHasRegistered) {
if ([self.chartView.chart.valueType isEqualToString:#"ph"]) {
if ([self.chartView pointIsWithinBoundsForPrimaryAxisValue:currentEnthalpy secondaryAxisValue:currentPressure]) {
[self.chartView moveMarkerToPrimaryAxisValue:currentEnthalpy
secondaryAxisValue:currentPressure];
} else {
[self.chartView removeMarker];
}
} else if ([self.chartView.chart.valueType isEqualToString:#"pv"]) {
if ([self.chartView pointIsWithinBoundsForPrimaryAxisValue:currentSpecVolume secondaryAxisValue:currentPressure]) {
[self.chartView moveMarkerToPrimaryAxisValue:currentSpecVolume
secondaryAxisValue:currentPressure];
} else {
[self.chartView removeMarker];
}
} else if ([self.chartView.chart.valueType isEqualToString:#"ts"]) {
if ([self.chartView pointIsWithinBoundsForPrimaryAxisValue:currentEntropy secondaryAxisValue:currentTemp]) {
[self.chartView moveMarkerToPrimaryAxisValue:currentEntropy
secondaryAxisValue:currentTemp];
} else {
[self.chartView removeMarker];
}
} else {
touchHasRegistered = NO;
[self.chartView removeMarker];
}
}
}
}
UISegmentedControl look like a lot to setup, but actually is not.
The following code just shows more detailed control in color and label positions inside the segments. If there is no further use somewhere else, there is no property needed to hold UISegmentedControl *. Call this once in -initWithFrame: or -viewDidLoad.
- (void)setupSegmentCtrl {
UISegmentedControl *segmentedCtrl = [[UISegmentedControl alloc] initWithItems:#[#"A",#"B",#"C"]];
segmentedCtrl.momentary = YES;
NSUInteger segItems = segmentedCtrl.numberOfSegments;
segmentedCtrl.frame = CGRectMake(0, 0, 60*segItems, 40);
// sorry - funny color scheme used to demonstrate
segmentedCtrl.tintColor = UIColor.orangeColor;
//segmentedCtrl.backgroundColor = UIColor.clearColor;
UIColor *dark = [UIColor colorWithWhite:0.5 alpha:0.5];
[segmentedCtrl setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:dark,NSForegroundColorAttributeName, [UIFont fontWithName:#"HelveticaNeue-Light" size:16.0],NSFontAttributeName, nil] forState:UIControlStateNormal];
[segmentedCtrl setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:UIColor.redColor, NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
[segmentedCtrl setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:UIColor.greenColor, NSForegroundColorAttributeName, nil] forState:UIControlStateHighlighted];
// you can move the segments labels about some pixels with the following..
//[segmentedCtrl setContentPositionAdjustment:UIOffsetMake(-1, -2) forSegmentType:UISegmentedControlSegmentAny barMetrics:UIBarMetricsDefault];
// manually set an active index, .. as default
[segmentedCtrl setSelectedSegmentIndex:0];
[self.view addSubview:segmentedCtrl];
// next lines work for all UIControls, setting a target and action manually.
// there are a lot UIControlEvent to choose/combine from available
[segmentedCtrl addTarget:self action:#selector(segmentSelectedAction:) forControlEvents:UIControlEventValueChanged];
}
and as defined you will want a method that takes action when you touch the segments.
-(void)segmentSelectedAction:(UISegmentedControl *)seg {
NSLog(#"selectedSegmentIndex=%d", seg.selectedSegmentIndex);
// what ever you gonna do with the seg.selectedSegmentIndex
}
and maybe good to know when using UISegmentedControl, when going in dark mode it has different color scheme for the background. So switch and test how it looks like.
If you have to change layout cause of device rotates, you will have to expose UISegmentedControl *segmentCtrl as property or class variable and change frame and so on in -layoutSubviews to your needs.
A last word to UIViews and UIGestureRecognizers. Sometime its much more practical to write your own UIView subclass and allocate that instead. Then you are able to use the following methods inside your subclass to catch touches directly.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
for (UITouch *touch in touches) {
NSLog(#"touchesBegan= %#",touch.description);
}
}
// and the other possible..
-(void)touchesMoved:withEvent:
-(void)touchesEnded:withEvent:
-(void)touchesCancelled:withEvent:
How to get the black blocks disappear?
And after the rotation, the black blocks disappear.
AppDelegate Source File:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController = [mainStoryBoard instantiateViewControllerWithIdentifier:#"ViewController"];
self.window.rootViewController = viewController;
bar = [KodUserCenterBar instance];
[self.window makeKeyAndVisible];
return YES;
}
Header File:
#interface KodUserCenterBar : UIWindow
/**获取单例
*/
+ (instancetype)instance;
/**显示工具栏
*/
+ (void)show;
/**隐藏工具栏
*/
+ (void)hide;
/**显示功能视图
*/
+ (void)showFunctionView;
/**隐藏功能视图
*/
+ (void)hideFunctionView;
#end
Source File:
#define WIDTH self.frame.size.width
#define HEIGHT self.frame.size.height
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define kBarWidth 200
#define kBarImageViewTag 100
#define kBarItemGap 5
#define degreesToRadian(x) (M_PI * (x) / 180.0)
#interface KodUserCenterBarFunctionItemObject : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, assign) NSUInteger indexOfTabBar;
#property (nonatomic, copy) NSString *imageName;
+ (instancetype)objectWithTitle:(NSString *)title indexOfTabBar:(NSUInteger)index imageName:(NSString *)imageName;
#end
#implementation KodUserCenterBarFunctionItemObject
+ (instancetype)objectWithTitle:(NSString *)title indexOfTabBar:(NSUInteger)index imageName:(NSString *)imageName
{
KodUserCenterBarFunctionItemObject *obj = [KodUserCenterBarFunctionItemObject new];
if (obj) {
obj.title = title;
obj.indexOfTabBar = index;
obj.imageName = imageName;
}
return obj;
}
#end
#interface KodUserCenterBar()
{
UIPanGestureRecognizer *pan;
UIViewController *_rootVC;
}
#property (nonatomic, copy) NSArray *itemsOfBar;
#property (nonatomic, assign) CGFloat initWidth;
#property (atomic, strong) UIButton *button;
#end
static KodUserCenterBar *static_instance = nil;
static BOOL isShowMenu = NO;
#implementation KodUserCenterBar
+ (instancetype)instance
{
if (static_instance == nil) {
static_instance = [KodUserCenterBar new];
[static_instance addTopButton];
}
return static_instance;
}
+ (void)show
{
[KodUserCenterBar instance].hidden = NO;
}
+ (void)hide
{
[KodUserCenterBar instance].hidden = YES;
}
+ (void)showFunctionView
{
if (!isShowMenu) {
[[KodUserCenterBar instance] clickBar:nil];
}
}
+ (void)hideFunctionView
{
if (isShowMenu) {
[[KodUserCenterBar instance] clickBar:nil];
}
}
- (instancetype)init
{
if (self = [super init]) {
self.backgroundColor = [UIColor clearColor];
self.windowLevel = UIWindowLevelAlert;
self.userInteractionEnabled = YES;
[self makeKeyAndVisible];
self.sd_x = 0;
self.sd_center_y = [UIScreen mainScreen].bounds.size.height / 2;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
return self;
}
- (NSArray *)itemsOfBar
{
if (_itemsOfBar == nil) {
KodUserCenterBarFunctionItemObject *item1 = [KodUserCenterBarFunctionItemObject objectWithTitle:#"个人中心" indexOfTabBar:0 imageName:#"tb3_toolbaruser"];
KodUserCenterBarFunctionItemObject *item2 = [KodUserCenterBarFunctionItemObject objectWithTitle:#"游戏礼包" indexOfTabBar:1 imageName:#"tb3_toolbargame"];
KodUserCenterBarFunctionItemObject *item3 = [KodUserCenterBarFunctionItemObject objectWithTitle:#"系统公告" indexOfTabBar:2 imageName:#"tb3_toolbarmsg"];
KodUserCenterBarFunctionItemObject *item4 = [KodUserCenterBarFunctionItemObject objectWithTitle:#"游戏论坛" indexOfTabBar:3 imageName:#"tb3_toolbarbbs"];
NSArray *data = #[item1, item2, item3, item4];
_itemsOfBar = [NSArray arrayWithArray:data];
}
return _itemsOfBar;
}
- (void)onDeviceOrientationChange
{
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
NSLog(#"is portrait");
NSLog(#"width = %f, height = %f", kScreenWidth, kScreenHeight);
[self adjustWindowPosition];
self.sd_center_y = kScreenHeight / 2;
}
else if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
NSLog(#"is landscape");
NSLog(#"width = %f, height = %f", kScreenWidth, kScreenHeight);
[self adjustWindowPosition];
self.sd_center_y = kScreenHeight / 2;
}
}
- (void)addTopButton
{
pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(dragBar:)];
pan.delaysTouchesBegan = NO;
[self addGestureRecognizer:pan];
UIViewController *vc = [[KodBasicViewController alloc] init];
vc.view.backgroundColor = [UIColor clearColor];
self.rootViewController = vc;
CGSize size = [UIImage imageNamed:#"tb3_assi_nor"].size;
self.sd_width = size.width;
self.sd_height = size.height;
self.initWidth = size.width;
_button = [[UIButton alloc] init];
[_button setBackgroundImage:[UIImage imageNamed:#"tb3_assi_nor"] forState:UIControlStateNormal];
[_button setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateHighlighted];
[_button setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateSelected];
_button.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[_button addTarget:self action:#selector(clickBar:) forControlEvents:UIControlEventTouchUpInside];
_button.userInteractionEnabled = YES;
_button.selected = NO;
[_button becomeFirstResponder];
[vc.view addSubview:_button];
}
- (void)clickBar:(id)button
{
NSTimeInterval interval = 0.2;
__weak typeof(_button) weakButton = _button;
isShowMenu = !isShowMenu;
pan.enabled = !isShowMenu;
if (self.sd_center_x > kScreenWidth / 2) {
[UIView animateWithDuration:interval animations:^{
self.sd_x = kScreenWidth;
} completion:^(BOOL finished) {
if (isShowMenu) {
self.sd_width = kBarWidth + self.initWidth;
_button.sd_right_x = self.sd_width;
UIImage *image = [UIImage imageNamed:#"tb3_assi_bor_right"];
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 30, 1, 0)];
UIImageView *rightImageView = [[UIImageView alloc] initWithImage:image];
rightImageView.image = image;
rightImageView.sd_width = kBarWidth;
rightImageView.sd_right_x = _button.sd_x;
rightImageView.sd_center_y = _button.sd_center_y;
rightImageView.tag = kBarImageViewTag;
rightImageView.userInteractionEnabled = YES;
[self.rootViewController.view addSubview:rightImageView];
self.sd_x = kScreenWidth;
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_right"] forState:UIControlStateNormal];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_pre_right"] forState:UIControlStateSelected];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_pre_right"] forState:UIControlStateHighlighted];
[self addFunctionItems:NO];
}
else {
self.sd_width = self.initWidth;
_button.sd_right_x = self.sd_width;
UIView *contentView = [self.rootViewController.view viewWithTag:kBarImageViewTag];
[contentView removeFromSuperview];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_nor"] forState:UIControlStateNormal];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateSelected];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateHighlighted];
}
[UIView animateWithDuration:interval animations:^{
self.sd_right_x = kScreenWidth;
}];
}];
}
else {
[UIView animateWithDuration:interval animations:^{
self.sd_right_x = 0;
} completion:^(BOOL finished) {
if (isShowMenu) {
self.sd_width = kBarWidth + self.initWidth;
UIImage *image = [UIImage imageNamed:#"tb3_assi_bor_left"];
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 0, 1, 30)];
UIImageView *leftImageView = [[UIImageView alloc] initWithImage:image];
leftImageView.image = image;
leftImageView.sd_width = kBarWidth;
leftImageView.sd_x = _button.sd_right_x;
leftImageView.sd_center_y = _button.sd_center_y;
leftImageView.tag = kBarImageViewTag;
leftImageView.userInteractionEnabled = YES;
[self.rootViewController.view addSubview:leftImageView];
self.sd_right_x = 0;
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_left"] forState:UIControlStateNormal];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_pre_left"] forState:UIControlStateSelected];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_act_pre_left"] forState:UIControlStateHighlighted];
[self addFunctionItems:YES];
}
else {
self.sd_width = self.initWidth;
UIView *contentView = [self.rootViewController.view viewWithTag:kBarImageViewTag];
[contentView removeFromSuperview];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_nor"] forState:UIControlStateNormal];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateSelected];
[weakButton setBackgroundImage:[UIImage imageNamed:#"tb3_assi_pre"] forState:UIControlStateHighlighted];
}
[UIView animateWithDuration:interval animations:^{
self.sd_x = 0;
}];
}];
}
}
- (void)addFunctionItems:(BOOL)isLeft
{
UIView *bgView = [self.rootViewController.view viewWithTag:kBarImageViewTag];
if (bgView) {
[self.itemsOfBar enumerateObjectsUsingBlock:^(KodUserCenterBarFunctionItemObject *obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([bgView viewWithTag:idx] == nil) {
KodFrameTabBarItem *item = [[KodFrameTabBarItem alloc] init];
item.tag = idx;
item.title = obj.title;
item.imageName = obj.imageName;
item.sd_width = (bgView.sd_width - _itemsOfBar.count * kBarItemGap - 10) / _itemsOfBar.count;
item.sd_height = bgView.sd_height;
item.sd_center_y = bgView.sd_height / 2;
item.sd_center_x = kBarItemGap + idx * (item.sd_width + kBarItemGap) + item.sd_width / 2;
item.sd_center_x += isLeft ? 0 : item.sd_width / 4;
[item addTarget:self action:#selector(clickItem:) forControlEvents:UIControlEventTouchUpInside];
[bgView addSubview:item];
}
}];
}
}
- (void)clickItem:(id)sender
{
[KodNavigationView showWithIndex:0];
[[UIApplication sharedApplication].keyWindow addSubview:[KodNavigationView instance]];
}
- (void)adjustWindowPosition
{
if (self.sd_center_x < kScreenWidth / 2) {
self.sd_x = 0;
}
else {
self.sd_right_x = kScreenWidth;
}
}
- (void)dragBar:(UIPanGestureRecognizer *)p
{
CGPoint panPoint = [p locationInView:[[UIApplication sharedApplication] keyWindow]];
if (p.state == UIGestureRecognizerStateBegan) {
if (_button) {
_button.selected = YES;
}
}
else if(p.state == UIGestureRecognizerStateChanged) {
self.center = CGPointMake(panPoint.x, panPoint.y);
if (panPoint.x < WIDTH / 2) {
self.sd_x = 0;
}
else if (panPoint.x > kScreenWidth - WIDTH / 2) {
self.sd_right_x = kScreenWidth;
}
if (panPoint.y < HEIGHT / 2) {
self.sd_y = 0;
}
else if (panPoint.y > kScreenHeight - HEIGHT / 2) {
self.sd_bottom_y = kScreenHeight;
}
}
else if(p.state == UIGestureRecognizerStateEnded) {
if(panPoint.x <= kScreenWidth / 2) {
[UIView animateWithDuration:0.2 animations:^{
self.sd_x = 0;
} completion:nil];
}
else {
[UIView animateWithDuration:0.2 animations:^{
self.sd_right_x = kScreenWidth;
} completion:nil];
}
if (_button) {
_button.selected = NO;
}
}
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#end
Root ViewController
Source File Of Root ViewController:
#interface KodBasicViewController ()
#end
#implementation KodBasicViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
UIWindow *window = self.view.window;
[window bringSubviewToFront:window.rootViewController.view];
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
UIWindow *window = self.view.window;
[window bringSubviewToFront:window.rootViewController.view];
}
#end
Here is my solution to this problem:
window.layer.masksToBounds = true
It's the default background colour of UIWindow instance, and while your root view is doing rotation, those uncovered parts will be shown as black block as you said.
You can just set your desired background colour for your window (or make your root view's frame big enough to cover whole window while doing rotation, not recommended):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window setBackgroundColor:[UIColor lightGrayColor]];
[self.window makeKeyAndVisible];
return YES;
}
I have a parent->child navigation setup in application. I use navigation via pushViewController function.
-(void)loadMemosViewController:(id)sender{
if(activeHullGuid != nil && activeHullGuid.length > 0)
{
NSString *storyboardName = #"MainStoryboard_iPhone1";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
MemosViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:#"sid_Memos"];
loginVC.keyReference = [[KeyValuePairIS alloc] initWithData:&controllerID:activeHullGuid];
[self.navigationController pushViewController:loginVC animated:YES];
}
}
for back navigation I use only default implementation in IOS (that would be a click on a back button).
This setup works for most situations, but recent implementation is causing problems.
The problem is this:
I have parent view controller named "hullViewController" and a child "memosViewController". The navigation between them works. Child does not report any information back to parent. HullViewController is also an editable form, which changes edit state via button in navigation bar.
Now if I change this edit/read state on hullViewController works nonstop. If I visit the child memosViewController, and go back to parent, I can only change state once more, then application crashes with exc_bad_access code=1.
After profiling with "Zombies" I found the culprit for exception is my probably disposed child memosViewController.
An Objective-C message was sent to a deallocated 'MemosViewController' object (zombie) at address: 0xdd52f10
it seams to crash on an IOS internal event, since none of my breakpoints are hit before crash.
A you can see the child is instanced during creation and I don't reference it to nothing else. Why would the edit state change request the child object?
What I tried already:
-declaring MemosViewController as a class variable. (application did not crash anymore, but would not change state anymore).
-initialising MemosViewController on viewDidLoad, changed nothing.
-calling child with class init only (not via storyboard), loaded child without UI, but result was same.
Project is set up with ARC, so I have minimum control on disposal of objects.
I have been searching for a solution quite a while now, with no results. Any help to solve my error editing if I visit the child would be appreciated.
UPDATE
I have additionally discovered, that when I get back to parent from child, the reference self.navigationItem still points to child, and any update to navigation buttons crashes the app.
**attaching custom ViewController, since it could be related to problem **
#import "UITableViewControllerEx.h"
#import "UITextFieldEx.h"
#import "UITextViewEx.h"
#import "GlobalValues.h"
#import "UITableViewEx.h"
#interface UITableViewControllerEx ()
#end
#implementation UITableViewControllerEx
UIBarButtonItem *bbi_navigateToMaster;
UIBarButtonItem *editButton;
UIButton *cmdEdit;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self setNavigationBackground];
[self setApplicationTintColor];
[self setApplicationTitleFont];
[self setupLeftBarButtonItem];
[self setBackButton];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//UITextFieldEx delegate to control the length of fields
- (BOOL)textField:(UITextFieldEx *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > textField.maxLength) ? NO : YES;
}
//UITextViewEx delegate to control the length of fields
-(BOOL)textView:(UITextViewEx *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
NSUInteger newLength = [textView.text length] + [text length] - range.length;
return (newLength > textView.maxLength) ? NO : YES;
}
//function to set left button to always pop to root controller
- (void)setBackButtonToReturnToMaster {
UIButton *cmdHome = [[UIButton alloc] initWithFrame:CGRectMake(0,0,30,30)];
[cmdHome setImage:[UIImage imageNamed:#"home"] forState:UIControlStateNormal];
bbi_navigateToMaster = [[UIBarButtonItem alloc] initWithCustomView:cmdHome];
[cmdHome addTarget:self action:#selector(backToMaster:) forControlEvents:UIControlEventTouchUpInside ];
self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:bbi_navigateToMaster , nil];
/*
bbi_navigateToMaster = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:self action:#selector(backToMaster:)];
self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:bbi_navigateToMaster , nil];
[bbi_navigateToMaster setImage:[UIImage imageNamed:#"home"]];
[bbi_navigateToMaster setImageInsets:UIEdgeInsetsMake(2, 2, 2, 2)];*/
}
//pop to root controller
-(void)backToMaster:(id)sender {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
}
else { [self.navigationController popToRootViewControllerAnimated:YES]; }
}
//find superview element of given type
- (UIView *)findSuperViewWithClass:(Class)superViewClass uiViewToSearch:(UIView*)bottomView{
UIView *superView = bottomView.superview;
UIView *foundSuperView = nil;
while (nil != superView && nil == foundSuperView) {
if ([superView isKindOfClass:superViewClass]) {
foundSuperView = superView;
break;
} else {
superView = superView.superview;
}
}
return foundSuperView;
}
-(void)setNavigationBackground{
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
UIImage *image = [UIImage imageNamed:#"navigationBackground"];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
UIView* uv = [[UIView alloc] initWithFrame:CGRectMake(0, self.navigationController.navigationBar.frame.size.height-1,self.navigationController.navigationBar.frame.size.width, 1)];
[uv setBackgroundColor:[GlobalValues getTintColor]];
[self.navigationController.navigationBar insertSubview:uv atIndex:10];
}
}
//sets the tint color of szstem items (title, szstem buttons, ...)
-(void)setApplicationTintColor {
NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ([[ver objectAtIndex:0] intValue] >= 7) {
self.navigationController.navigationBar.barTintColor = [GlobalValues getTintColor];
self.navigationController.navigationBar.tintColor = [GlobalValues getTintColor];
self.navigationController.navigationBar.translucent = NO;
[self.navigationController.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
UIColor *color = [GlobalValues getTintColor];
self.view.tintColor = color;
}else {
//self.navigationController.navigationBar.tintColor = [GlobalValues getTintColor];
/*NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil];
[[UINavigationBar appearance] setTitleTextAttributes:textTitleOptions];*/
}
}
//sets the navigation title
-(void)setApplicationTitleFont {
NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ([[ver objectAtIndex:0] intValue] >= 7) {
[self.navigationController.navigationBar setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"HelveticaNeue-Light" size:21],
NSFontAttributeName, [UIColor whiteColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil]];
}else {
[self.navigationController.navigationBar setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeFont: [UIFont fontWithName:#"Helvetica-Light" size:21.0f]
}];
}
}
-(void)setupLeftBarButtonItem{
cmdEdit = [[UIButton alloc] initWithFrame:CGRectMake(0,0,30,30)];
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
editButton = [[UIBarButtonItem alloc] initWithCustomView:cmdEdit];
[cmdEdit addTarget:self action:#selector(setEditState) forControlEvents:UIControlEventTouchUpInside];
}
- (UIBarButtonItem *)leftBarButtonItem
{
if (self.tableView.editing) {
[cmdEdit setImage:[UIImage imageNamed:#"unlocked"] forState:UIControlStateNormal];
return editButton;
}
else {
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
return editButton;
}
}
-(void)updateEditButton{
if (self.tableView.editing) {
[cmdEdit setImage:[UIImage imageNamed:#"unlocked"] forState:UIControlStateNormal];
}
else {
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
}
}
-(void)setEditState{
if (!self.tableView.editing) {
[self setEditing:YES animated:YES];
} else {
[self setEditing:NO animated:YES];
}
[self updateEditButton];
}
}*/
-(void) setBackButton{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"back"] ;
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(goback) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 30, 30);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;
self.navigationItem.leftBarButtonItem = backButton;
}
- (void)goback
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - Table view data source
#pragma mark - Table view delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundView=[[UIView alloc] initWithFrame:CGRectZero];
cell.backgroundColor = [UIColor clearColor];
cell.layer.backgroundColor = [UIColor clearColor].CGColor;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *customTitleView = [ [UIView alloc] initWithFrame:CGRectMake(10, 0, 300, 44)];
UIView *customTitleLineView = [ [UIView alloc] initWithFrame:CGRectMake(10, 43, self.view.frame.size.width -20, 0.5f)];
customTitleLineView.backgroundColor = [GlobalValues getTintColor];
UILabel *titleLabel = [ [UILabel alloc] initWithFrame:CGRectMake(20, 0, 300, 44)];
titleLabel.text = [self tableView:tableView titleForHeaderInSection:section];
titleLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:18];
titleLabel.textColor = [GlobalValues getTintColor];
titleLabel.backgroundColor = [UIColor clearColor];
if (titleLabel.text.length != 0) {
[customTitleView addSubview:customTitleLineView];
}
[customTitleView addSubview:titleLabel];
return customTitleView;
}
#end
Seems I have found a solution to my problem.
Class UITableViewControllerEx contains functionality to setup edit button. The class variable "UIBarButtonItem *editButton;" is then used as edit button on all forms that inherit from "UITableViewControllerEx"
the solution was to instantiate UIBarButtonItem on each form inheriting UITableViewControllerEx with local name (like editButtonHull) and given as param to logic of superclass.
Thanks to #akashg for suggestion that Navigation bar modification might be the problem
I'm working on a big game, but i can't seem to get started.
When i run this code, i can see it reaches the main view, but when i use the simulator i just get a blank image. Any advice?
Also i dragged the main view from another project as it would seem that no one has any idea how to create a MainView
#import "JKGAppDelegate.h"
#implementation JKGAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
mainView = [[MainView alloc] initWithFrame: [UIScreen mainScreen].applicationFrame];
mainView.backgroundColor = [UIColor grayColor];
[self.window addSubview: mainView];
[self.window makeKeyAndVisible];
return YES;
}
- (void) startGameLoop {
NSString *deviceOS = [[UIDevice currentDevice] systemVersion];
bool forceTimerVariant = TRUE;
if (forceTimerVariant || [deviceOS compare: #"3.1" options: NSNumericSearch] == NSOrderedAscending) {
//33 frames per second -> timestep between the frames = 1/33
NSTimeInterval fpsDelta = 0.0303;
timer = [NSTimer scheduledTimerWithTimeInterval: fpsDelta
target: self
selector: #selector( loop )
userInfo: nil
repeats: YES];
} else {
int frameLink = 2;
timer = [NSClassFromString(#"CADisplayLink") displayLinkWithTarget: self selector: #selector( loop )];
[timer setFrameInterval: frameLink];
[timer addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
}
NSLog(#"Game Loop timer instance: %#", timer);
}
- (void) stopGameLoop {
[timer invalidate];
timer = nil;
}
- (void) loop {
[mainView setNeedsDisplay]; //triggers MainView's drawRect:-method
}
- (void) applicationDidBecomeActive: (UIApplication *) application {
[self startGameLoop];
}
- (void) applicationWillResignActive: (UIApplication *) application {
[self stopGameLoop];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {}
- (void)applicationWillEnterForeground:(UIApplication *)application {}
- (void)applicationWillTerminate:(UIApplication *)application {}
- (void) dealloc {
[self stopGameLoop];
}
#end
#import "MainView.h"
int W=1024;
int H=768;
#implementation MainView
-(int) getRndBtw: (int) bottom and: (int) top{
int rnd = bottom + (arc4random()% (top+1-bottom));
return rnd;
}
- (void) drawRect: (CGRect) rect {
W = rect.size.width;
H = rect.size.height;
static int cnt = 0;
cnt++;
NSLog(#"Game Loop: %i", cnt);
//if (!carBlueImage) {
carBlueImage = [UIImage imageNamed: #"derp.png"];
static int y = 0;
y += 3;
if (y > H) y = -100;
[carBlueImage drawAtPoint: CGPointMake(y, H/2)];
for(int i = 0; i < 50; i++){
int x;
int y;
x = [self getRndBtw:0 and:W];
y = [self getRndBtw:0 and:H];
[carBlueImage drawAtPoint:CGPointMake(x, y)];
x = [self getRndBtw:0 and:H];
y = [self getRndBtw:0 and:W];
NSLog(#"ADT");
[carBlueImage drawAtPoint:CGPointMake(x, y)];
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(gc, 1, 1, 1, 1);
CGContextMoveToPoint(gc, 0, 0);
CGContextAddLineToPoint(gc, W, H);
CGContextStrokePath(gc);
}
NSMutableArray *arrayOfImageViews = [NSMutableArray array];
for (int i = 0; i < 30; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"map.png"]];
//[self.view addSubview:imageView];
[arrayOfImageViews addObject:imageView];
}
}
#end
JKGAppDelegate.h
#property(nonatomic,strong) UIViewController *viewController;
JKGAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
mainView = [[MainView alloc] initWithFrame: [UIScreen mainScreen].applicationFrame];
mainView.backgroundColor = [UIColor grayColor];
self.viewController = [[UIViewController alloc] initWithNibName:#"viewController"];
[self.viewController.view addSubview:mainView];
self.window.rootViewController = self.viewController;
[self.window addSubview: mainView];
[self.window makeKeyAndVisible];
return YES;
}
I need to add a UIView to the main window, the UIView consists in a view with some buttons.
The problem is, the buttons i put inside that view, is not responding for the touch events,
like it have some view in front of it.
That view need to be a singleton class, cause i need to respond the touchevent in any class.
Heres the code for the UIView :
+ (MenuBarView *)sharedMenuBar
{
static MenuBarView *sharedSingleton;
#synchronized(self) {
if (!sharedSingleton) sharedSingleton = [[MenuBarView alloc] init];
return sharedSingleton;
}
}
-(id)init
{
self = [super init];
if(self)
{
self.userInteractionEnabled = YES;
backgroundBarImage = [UIImage imageNamed:#"Barra.png"];
UIImageView * backgroundBar = [[UIImageView alloc]initWithImage:backgroundBarImage];
backgroundBar.contentMode = UIViewContentModeCenter;
backgroundBar.backgroundColor = [UIColor clearColor];
[backgroundBar setFrame:CGRectMake(0, 0, backgroundBarImage.size.width, backgroundBarImage.size.height)];
[self addSubview:backgroundBar];
UIButton * rootBTN = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[rootBTN setFrame:CGRectMake(0, 8, 100, 40)];
[rootBTN addTarget:self action:#selector(selectedBarButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:rootBTN];
UIImage * localizacaoIMG = [UIImage imageNamed:#"Localizador"];
UIImageView * localizacaoView = [[UIImageView alloc]initWithImage:localizacaoIMG];
localizacaoView.contentMode = UIViewContentModeScaleAspectFill;
[localizacaoView setFrame:CGRectMake(backgroundBar.frame.origin.x+130, 8, localizacaoIMG.size.width, localizacaoIMG.size.height)];
[backgroundBar addSubview:localizacaoView];
UIButton * localizacaoBTN = [UIButton buttonWithType:UIButtonTypeCustom];
[localizacaoBTN setFrame:CGRectMake(backgroundBar.frame.origin.x+110, 8, 60, 40)];
localizacaoBTN.tag = 1;
[self addSubview:localizacaoBTN];
}
return self;
}
//The event handling method
-(void)selectedBarButton:(UIButton *)sender
{
NSLog(#"OK");
[self.delegate selectedMenuBar:sender.tag];
}
and heres the implementation on the AppDelegate :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[InitialViewController alloc] init];
self.navController = [[EzMallNavViewController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
if(IS_IPOD)
{
[[MenuBarView sharedMenuBar]setFrame:CGRectMake(0, self.window.frame.size.height-51, [MenuBarView sharedMenuBar].frame.size.width, [MenuBarView sharedMenuBar].frame.size.height)];
}
else
{
[[MenuBarView sharedMenuBar]setFrame:CGRectMake(0, self.window.frame.size.height, [MenuBarView sharedMenuBar].frame.size.width, [MenuBarView sharedMenuBar].frame.size.height)];
}
[MenuBarView sharedMenuBar].delegate = self;
[self.window addSubview:[MenuBarView sharedMenuBar]];
return YES;
}
#pragma mark MenuBarDelegateMethods
-(void)selectedMenuBar:(int) tag
{
NSLog(#"Here");
}
It looks like your menu view has a zero size frame so no touches are detected. The buttons appear on screen because the menu view isn't set to clip drawing to its bounds.
Try to set different color for different views and analyze the view hierarchy ,it might be possible that you have added the view in wrong order .