I am trying to put an overlay on top of status bar by doing the following :
ViewController implementation
- (IBAction)addViewOnTop:(id)sender {
StatusBarOverlayWindow *overlay = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
overlay.hidden = NO;
[overlay makeKeyAndVisible];
}
StatusBarOverlayWindow header file
#import <UIKit/UIKit.h>
#interface StatusBarOverlayWindow : UIWindow {
}
#end
StatusBarOverLayWindow implementation
#implementation StatusBarOverlayWindow
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Place the window on the correct level and position
self.windowLevel = UIWindowLevelStatusBar + 1;
self.frame = frame;
self.backgroundColor = [UIColor orangeColor];
}
return self;
}
#end
When I click a button, nothing happens at all.
Does anyone have any thoughts about this issue. Please guide, thanks
Try keeping a strong reference to the StatusBarOverlayWindow, without that the variable will go out of scope after the addViewOnTop: method is complete. A property will work well here.
Example:
#interface ViewController : UIViewController
#property (nonatomic, strong) StatusBarOverlayWindow *overlayWindow;
#end
Then in your method:
- (IBAction)addViewOnTop:(id)sender {
self.overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
overlay.hidden = NO;
[overlay makeKeyAndVisible];
}
Related
How can I get this kind of method refactored better?
This is just a sample in my objective-c project, and I am trying to do it all programmatically
Im not sure what the best practices would be, create a protocol? an extension? or refactor further down to additional methods?
- (void)viewDidLoad {
[super viewDidLoad];
// Label to be changed
label = [[UILabel alloc]init];
label.text = #"Changed with code!";
[self.view addSubview:label];
// Label Constraints
label.translatesAutoresizingMaskIntoConstraints = NO;
[label.topAnchor constraintEqualToAnchor: self.view.safeAreaLayoutGuide.topAnchor constant:50].active = YES;
[label.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:20].active = YES;
[label.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-20].active = YES;
}
As an example you could create a UIView subclass that creates the label and makes the layout.
#interface MyView: UIView
#property (nonatomic, strong, readonly) UILabel *label;
#end
#interface ViewController: UIViewController
#property (nonatomic, strong, readonly) MyView *myView;
#end
#implementation MyView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_label.translatesAutoresizingMaskIntoConstraints = NO;
UILayoutGuide *safeAreaLayoutGuide = self.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:#[
[label.topAnchor constraintEqualToAnchor: safeAreaLayoutGuide.topAnchor constant:50],
[label.leadingAnchor constraintEqualToAnchor:safeAreaLayoutGuide.leadingAnchor constant:20],
[label.trailingAnchor constraintEqualToAnchor:safeAreaLayoutGuide.trailingAnchor constant:-20]
]];
}
return self;
}
#end
#implementation MyViewController
- (void)loadView {
self.view = [[MyView alloc] initWithFrame:CGRectZero];
}
- (MyView *)myView {
return (id)self.view; // it makes view to load regardless which
// property do you use – `view` or `myView`
}
- (void)viewDidLoad {
[super viewDidLoad];
self.myView.label.text = #"Changed with code!";
}
#end
For some reason when I launch my app it does everything correctly except show the user as blue dot on the map. It zooms in to the users current location, just no dot. Any help would be greatly appreciated.
I've added code and screenshots below for resources.
FrontViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface FrontViewController : UIViewController <CLLocationManagerDelegate>
{
CLLocationManager *objLocationManager;
double latitude_UserLocation, longitude_UserLocation;
}
#property (weak, nonatomic) IBOutlet MKMapView *objMapView;
#end
FrontViewController.m
#import "FrontViewController.h"
#import "SWRevealViewController.h"
#interface FrontViewController()
// Private Methods:
- (IBAction)pushExample:(id)sender;
#end
#implementation FrontViewController
#synthesize objMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadUserLocation];
//self.title = NSLocalizedString(#"Front View", nil);
SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
[self.navigationController.navigationBar addGestureRecognizer:revealController.panGestureRecognizer];
UIBarButtonItem *revealButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"reveal-icon.png"]
style:UIBarButtonItemStyleBordered target:revealController action:#selector(revealToggle:)];
self.navigationItem.leftBarButtonItem = revealButtonItem;
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"BSEEK-Logo.png"]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
UIView* titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 84, 84)];
imageView.frame = titleView.bounds;
[titleView addSubview:imageView];
self.navigationItem.titleView = titleView;
}
- (IBAction)pushExample:(id)sender
{
UIViewController *stubController = [[UIViewController alloc] init];
stubController.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:stubController animated:YES];
}
- (void) loadUserLocation
{
objLocationManager = [[CLLocationManager alloc] init];
objLocationManager.delegate = self;
objLocationManager.distanceFilter = kCLDistanceFilterNone;
objLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
if ([objLocationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[objLocationManager requestWhenInUseAuthorization];
}
[objLocationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0)
{
CLLocation *newLocation = [locations objectAtIndex:0];
latitude_UserLocation = newLocation.coordinate.latitude;
longitude_UserLocation = newLocation.coordinate.longitude;
[objLocationManager stopUpdatingLocation];
[self loadMapView];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[objLocationManager stopUpdatingLocation];
}
- (void) loadMapView
{
CLLocationCoordinate2D objCoor2D = {.latitude = latitude_UserLocation, .longitude = longitude_UserLocation};
MKCoordinateSpan objCoorSpan = {.latitudeDelta = 0.2, .longitudeDelta = 0.2};
MKCoordinateRegion objMapRegion = {objCoor2D, objCoorSpan};
[objMapView setRegion:objMapRegion];
}
#end
Project Files
MKMapView has a showsUserLocation property. It looks like you need to turn that on.
You can set that property in code, but if your map view is created in a storyboard scene you can just check the User Location box in the storyboard editor:
Also: Make sure you have the appropriate key in your Info.plist to allow the app to access the user's location, and that you've granted the app appropriate permission on the device. (You can check in Settings->Privacy->Location Services.) If the app doesn't have permission to get the location, the map won't show it even if showsUserLocation is enabled.
Please help me, I have been customizing a UIView class to set NSString value as a tag, but how can I get that view from view hierarchy.In UIView class default method to get view is viewWithTag:(NSInteger).
Please see below code
#import <UIKit/UIKit.h>
#interface UIView (StringTag)
#property (nonatomic, copy) NSString *tagString;
#end
#import "UIView+StringTag.h"
#import <objc/runtime.h>
static const void *tagKey = &tagKey;
#implementation UIView (StringTag)
- (void)setTagString:(NSString *)tagString
{
objc_setAssociatedObject(self, tagKey, tagString,OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (id)tagString
{
return objc_getAssociatedObject(self, tagKey);
}
#end
I want a method like viewWithStringTag:(NSString *)stringTag.
Thanks,
Use recursive search, includes self
#import <UIKit/UIKit.h>
#interface UIView (StringTag)
#property (nonatomic, copy) NSString *tagString;
- (UIView *)viewWithStringTag:(NSString *)strTag;
#end
#import "UIView+StringTag.h"
#import <objc/runtime.h>
static const void *tagKey = &tagKey;
#implementation UIView (StringTag)
- (void)setTagString:(NSString *)tagString
{
objc_setAssociatedObject(self, tagKey, tagString,OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (id)tagString
{
return objc_getAssociatedObject(self, tagKey);
}
- (UIView *)viewWithStringTag:(NSString *)strTag{
if ([self.tagString isEqual:strTag]){
return self;
}
if (!self.subviews.count){
return nil;
}
for (UIView *subview in self.subviews){
UIView *targetView = [subview viewWithStringTag:strTag];
if (targetView){
return targetView;
}
}
return nil;
}
#end
Here are my testing code
- (void)viewDidLoad {
[super viewDidLoad];
UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
aView.tagString = #"aView";
UIView *bView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
bView.tagString = #"bView";
[self.view addSubview:aView];
[aView addSubview:bView];
UIView *targetView = [self.view viewWithStringTag:#"bView"];
NSLog(#"%#", targetView);
// <UIView: 0x7f933bc21e50; frame = (0 0; 100 100); layer = <CALayer: 0x7f933bc1c430>>
}
I have a view which includes two subviews. I had it working so that only one subview was shown at a time and each subview had a button and when the button was clicked the subview would flip over and the next subview would appear. The problem was that it appeared as though the entire view was flipping. After reading on this site about how to solve the problem I attempted to add the subviews to a container and flip that instead. However now, although my first subview is showing up when I press the button it no longer flip. It doesn't do anything. I put a log statement in the method which flips the subviews, as well as a breakpoint and as far as I can tell it no longer gets called. I'm very new to xcode and objective c and delegates and I have no idea how to proceed. Any help would be appreciated. Thanks.
I have included the relevant code here:
The header for the ViewController
#interface ExerciseViewController : UIViewController<ExerciseSubViewDelegate>
//stuff for subviews
#property (nonatomic, strong) ExerciseSubViewImage *subViewImage;
#property (nonatomic, strong) ExerciseSubViewText *subViewText;
#property UIView *panel;
#end
This is the code for the ViewController:
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
#synthesize subViewImage, subViewText;
- (void)viewDidLoad
{
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
}
-(ExerciseSubViewImage *)subViewImage
{
if (!subViewImage)
{
CGRect subViewImageFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewImage = [[ExerciseSubViewImage alloc] initWithFrame:subViewImageFrame];
[_panel addSubview:subViewImage];
}
return subViewImage;
}
-(ExerciseSubViewText *)subViewText
{
if (!subViewText)
{
CGRect subViewTextFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewText = [[ExerciseSubViewText alloc] initWithFrame:subViewTextFrame];
self.subViewText.backgroundColor = [UIColor blueColor];
[_panel addSubview:subViewText];
}
return subViewText;
}
-(void)exerciseSubViewImagePressed
{
[UIView transitionWithView:_panel
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[subViewImage removeFromSuperview];
[_panel addSubview:subViewText];
}
completion: nil];
//This is how I did it before I added the container
/*[UIView transitionFromView:subViewImage
toView:subViewText
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewText.delegate = self;*/
NSLog(#"Ipushedtheimage");
}
-(void)exerciseSubViewTextPressed
{//I haven't updated this yet
[UIView transitionFromView:subViewText
toView:subViewImage
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewImage.delegate = self;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
subViewImage = nil;
subViewText = nil;
}
#end
This is the code for the delegate
#import
#protocol ExerciseSubViewDelegate <NSObject>
-(void) exerciseSubViewImagePressed;
-(void) exerciseSubViewTextPressed;
#end
I am also added the code for the first subview:
#import
#import "ExerciseSubViewDelegate.h"
#interface ExerciseSubViewImage : UIView
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, assign) id<ExerciseSubViewDelegate>delegate;
#property (strong, nonatomic) UIImageView *exerciseImageView;
#end
#import "ExerciseSubViewImage.h"
#import "UIImage+animatedGIF.h"
#implementation ExerciseSubViewImage
#synthesize button;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialization code
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect buttonFrame = CGRectMake(50,200,100,35);
self.button.frame = buttonFrame;
[self.button setTitle:#"Image"forState:UIControlStateNormal];
[self.button addTarget:self
action:#selector(buttonTouched)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
_exerciseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50,20,160,158)];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"AppleLogo" withExtension:#"gif"];
_exerciseImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
[self addSubview:self.exerciseImageView];
}
return self;
}
-(void)buttonTouched
{
NSLog(#"imagebuttonpressed");
[self.delegate exerciseSubViewImagePressed];
}
Again, any help would be appreciate. I know I'm probably just not understanding something simple.
Ok. This took me all weekend but I finally figured it out on my own. I thought I would shere the answer here in case anyone else ever has a similar problem. After trying several other approaches I finally went back to the approach I used here and started inserting a whole bunch of NSLogs to determine the order that every thing was executing in. What I finally ended up doing was changing this: (all in the top ViewController)
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
to this:
//create panel
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, s self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
//Set the subview delegates
self.subViewImage.delegate = self;
self.subViewText.delegate = self;
I want to write a custom UIView that does the following:
It takes an image and adds it to a view.
It has a method to flip that image.
I want to pass this Custom UIView to the iCarousel class:
https://github.com/nicklockwood/iCarousel
How can I create a custom UIView using Objective C and Cocoa?
I started by doing the following:
CItem.h
#import <UIKit/UIKit.h>
#interface CItem : UIView
{
UIImageView *box;
}
#property (nonatomic, retain) UIImageView * box;
#end
CItem.m
#import "CItem.h"
#implementation CItem
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
box = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, 240, 240)];
[box setImage:[UIImage imageNamed:# "cleaning.png"]];
[self addSubview:box];
}
#end
You should not add your addSubview: in drawRect:. See this method's disscussion:
Discussion
The default implementation of this method does nothing.
Subclasses that use native drawing technologies (such as Core Graphics
and UIKit) to draw their view’s content should override this method
and implement their drawing code there. You do not need to override
this method if your view sets its content in other ways. For example,
you do not need to override this method if your view just displays a
background color or if your view sets its content directly using the
underlying layer object. Similarly, you should not override this
method if your view uses OpenGL ES to do its drawing.
If you don't use a xib file for your CItem you can add your code to initWithFrame:.
//CItem.h
#import <UIKit/UIKit.h>
#interface CItem : UIView
- (void)flip;
#end
// CItem.m
#import "CItem.h"
#interface CItem()
#property (assign, nonatomic) BOOL displayingPrimary;
#property (strong, nonatomic) UIImageView *primaryView;
#property (strong, nonatomic) UIImageView *secondaryView;
#end
#implementation CItem
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_primaryView = [[UIImageView alloc] initWithFrame:frame];
[_primaryView setImage:[UIImage imageNamed:# "cleaning.jpg"]];
[self addSubview:_primaryView];
_secondaryView = [[UIImageView alloc] initWithFrame:frame];
[_secondaryView setImage:[UIImage imageNamed:# "adding.jpg"]];
[self addSubview:_secondaryView];
}
return self;
}
- (void)flip
{
[UIView transitionFromView:(self.displayingPrimary ? self.primaryView : self.secondaryView)
toView:(self.displayingPrimary ? self.secondaryView : self.primaryView)
duration:1.0
options:(self.displayingPrimary ? UIViewAnimationOptionTransitionFlipFromRight :
UIViewAnimationOptionTransitionFlipFromLeft) | UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished) {
if (finished) {
self.displayingPrimary = !self.displayingPrimary;
}
}];
}
#end
Then you can use CItem like this:
CItem *subView = [[CItem alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
[self.view addSubview:subView];
You should only implement drawRect if you intend to do custom drawing. If you want to use subviews you can just move your code into the initWithFrame:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
box = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 240.0f, 240.0f)];
[box setImage:[UIImage imageNamed:#"cleaning"]];
[self addSubview:box];
}
return self;
}
You can safely remove the drawRect method. Not sure what you mean by "flipping" the image, but you should be able to manipulate the imageView object using the "box" property of your custom class.