iOS trouble loading an image file to view from view controller programmatically - ios

I have a view with a property that should take an NSString from my view controller and display an image. If I hard code locationImageFile with "320x213-1.png" in my view, the image displays properly, but if I try to set locationImageFile from my view controller, the image doesn't appear. I feel like I'm missing something pretty basic. Side note: I seem to be able to set the locationTitle property from my view controller without any problems.
LocationViewController.m
#import "LocationViewController.h"
#import "LocationView.h"
#implementation LocationViewController
{
LocationView *_locationView;
}
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
_locationView = [[LocationView alloc] initWithFrame:frame];
[self setView:_locationView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_locationView.locationTitle.text = aLocation.name;
_locationView.locationImageFile = #"320x213-1.png";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
LocationView.m
#import "LocationView.h"
#implementation LocationView
#synthesize locationTitle;
#synthesize locationImageFile;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setBackgroundColor: [UIColor blueColor]];
// Image container
UIImage *locationImage = [UIImage imageNamed:locationImageFile];
UIImageView *locationImageContainer = [[UIImageView alloc] initWithImage:locationImage];
[locationImageContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
locationImageContainer.backgroundColor = [UIColor yellowColor];
[self addSubview:locationImageContainer];
// Text line
locationTitle = [[UILabel alloc]init];
[locationTitle setTranslatesAutoresizingMaskIntoConstraints:NO];
locationTitle.backgroundColor = [UIColor whiteColor];
[self addSubview:locationTitle];
}
return self;
}
#end

I think this is because the loadView method are invoke earlier than viewDidLoad method.
so when you set _locationView.locationImageFile = #"320x213-1.png";,the containerView's image are not being set.
You can consider declare locationImageContainer as a property of locationView , and set it's image directly.like
_locationView.locationImageContainer.image = [UIImage imageNamed:#"320x213-1.png"];
instead of setting locationImageFile as a property.

When LocationView is initialized, the value of the instance variable locationImageFile equals nil. Override the setter of the locationImageFile property inside LocationView.m like this:
- (void)setLocationImageFile:(NSString *)aLocationImageFile
{
locationImageFile = aLocationImageFile;
locationImageContainer.image = [UIImage imageNamed:aLocationImageFile];
}

You can try, doing it like this:
_locationView.locationImageFile = [UIImage imageNamed:locationImageFile];
if you did it like this:
_locationView.locationImageFile = locationImageFile;

Related

How to add headerView like Navigationbar on ASViewController with ASTableNode without NavigationController?

In my application, I do not use the NavigationController, in general.
In UITableView I would do so, would add
[Self.view addSubview: self.myCustomHeaderView];
But I'm using ASTableNode. If I do something, something similar here:
- (instancetype)init {
_tableNode = [[ASTableNode alloc] init];
self = [super initWithNode:_tableNode];
if (self) {
_tableNode.dataSource = self;
_tableNode.delegate = self;
self.navigationItem = //navigationItem implement
UINavigationBar *navbar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
navbar.backgroundColor = [UIColor redColor];
navbar.items = #[self.navigationItem];
ASDisplayNode *navBarNode = [[ASDisplayNode alloc] initWithViewBlock:^UIView * _Nonnull {
return navbar;
}];
[self.node addSubnode:navBarNode];
}
return self;
}
Then this node is added as part of the list and scrolled along with the list, and I need it to be as fixed header.
initWith ASDisplayNode rather than ASTableNode,then add table node on VC's node,for example:
#interface OCTextureTableController : ASViewController<ASDisplayNode *>
#property (nonatomic, strong) ASTableNode *tableNode;
- (instancetype)init
{
self = [super initWithNode:[ASDisplayNode new]];
if (self) {
self.tableNode = [[ASTableNode alloc] init];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableNode.backgroundColor = [UIColor yellowColor];
self.tableNode.frame = CGRectMake(0, NAVIGATION_BAR_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT-NAVIGATION_BAR_HEIGHT);
[self.node addSubnode:self.tableNode];
}
(i) take Class A as base Class.
(ii) take Class B as derived Class having type of class A.
Now in class A Add a uiview on top. that will be considered as navigation.(do anything in that view)
To use same navigation bar: you have to take other all classes as having type of class A.
that's it.

iOS self.navigationController.toolbar position to top doesn't change

I am trying to change self.navigationController.toolbar position to top instead of a bottom.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIToolbarDelegate, UIBarPositioningDelegate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// View did load
- (void)viewDidLoad
{
// Superclass view did load method call
[super viewDidLoad];
// UIToolbarDelegate
self.navigationController.toolbar.delegate = self;
}
- (void)viewDidLayoutSubviews
{
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.frame = CGRectMake(self.navigationController.toolbar.frame.origin.x, 64.0f, self.navigationController.toolbar.frame.size.width, self.navigationController.toolbar.frame.size.height);
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"First", #"Second"]];
segmentedControl.frame = CGRectMake(50.0f, 10.0f, 220.0f, 24.0f);
segmentedControl.selectedSegmentIndex = 1;
[self.navigationController.toolbar addSubview:segmentedControl];
}
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
#end
The position changes at first, but later gets back to the bottom. Please, help me!
First make sure that toolbar delegate method positionForBar: is get called. If not, then your toolbar delegate is not properly set and you've have to define the UIToolbarDelegate protocol inside your header class.
#interface ExampleViewController : UIViewController <UIToolbarDelegate>
...
#end
Then set the delegate and also change the frames for toolbar. However, for the orientation you might have to reconsider the frames of toolbar.
#implementation ExampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
// set the toolbar delegate
self.navigationController.toolbar.delegate = self;
self.navigationController.toolbarHidden = NO;
// create a toolbar child items
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"First", #"Second"]];
segmentedControl.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.with, 24.0f);
segmentedControl.selectedSegmentIndex = 1;
[self.navigationController.toolbar addSubview:segmentedControl];
// set the frames
CGRect toolbarFrame = self.navigationController.toolbar.frame;
toolbarFrame.origin.y = self.navigationController.frame.size.height;
self.navigationController.toolbar.frame = toolbarFrame;
}
// pragma mark - UIToolbarDelegate
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
#end
In your viewDidLoad method, add:
self.navigationController.toolbar.delegate = self;

Add category to UITextView and Override it's init function while UITextView is in xib

I can't intercept the init function that's getting called when it's getting created inside of the xib file.
I want to add borderline to it when it gets created so that I won't need to add it manually.
.h:
#import <UIKit/UIKit.h>
#interface UITextView (FITAddBorderline)
- (id) init;
- (id) initWithFrame:(CGRect)frame;
#end
.m:
#import "UITextView+FITAddBorderline.h"
#implementation UITextView (FITAddBorderline)
- (id) init
{
self = [super init];
if (self) {
[self addBorderline];
}
return self;
}
- (id) initWithFrame:(CGRect)frame {
self = [super init];
if (self) {
self.frame = frame;
[self addBorderline];
}
return self;
}
- (void) addBorderline {
//To make the border look very close to a UITextField
[self.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[self.layer setBorderWidth:2.0];
//The rounded corner part, where you specify your view's corner radius:
self.layer.cornerRadius = 5;
self.clipsToBounds = YES;
}
#end
Views that come from NIBs are initialized with initWithCoder:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self addBorderline];
}
return self;
}
As a side note, I would recommend changing what you are doing and use a subclass instead of a category. You can get yourself into some trouble overriding methods in a category. See more info here.
You just need to implement the awakeFromNib method:
-(void)awakeFromNib
{
[super awakeFromNib];
[self addBorderline];
}

iOS bottom align an object with programmatic auto layout constraints

I'm trying to position a button so that it is always an X amount of pixels from the bottom of the screen. The view is laid out programmatically using auto layout. If I use: #"V:|-44-[closeModalButton]" the object aligns 44 pixels from the top of the screen as expected. However, #"V:[closeModalButton]-44-|" causes the button to never show up. It seems like it ought to be pretty straightforward, so I feel like I'm missing something really obvious.
Implementation of view
#import "DetailView.h"
#implementation DetailView
#synthesize closeModalButton;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor whiteColor];
CGRect aFrame = [[UIScreen mainScreen] bounds];
self.frame = aFrame;
closeModalButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeModalButton setImage: [UIImage imageNamed:#"closeButton.png"] forState:UIControlStateNormal];
[closeModalButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:closeModalButton];
NSDictionary *viewArranging = NSDictionaryOfVariableBindings(closeModalButton);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[closeModalButton(44)]-44-|"
options:0
metrics:0
views:viewArranging]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-149-[closeModalButton(44)]-149-|"
options:0
metrics:0
views:viewArranging]];
}
return self;
}
#end
View controller
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
{
DetailView *_detailView;
}
- (void)loadView
{
_detailView = [[DetailView alloc] init];
[self setView:_detailView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[_detailView.closeModalButton addTarget:self
action:#selector(closeModalButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)closeModalButtonPressed:(UIButton *)sender{
[self dismissViewControllerAnimated:YES
completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Ok, so it looks like DetailView.h subclassed UIScrollView rather than UIView. Setting the proper subclass caused the constraints to operate as expected.

iOS setting view variable from view controller programmatically

I've created a view with a variable and loaded it in the loadView method of a view controller. How do I pass a value to the view variable from the view controller after the loadView method has been called?
LocationView.m
#import "LocationView.h"
#implementation LocationView
#synthesize locationTitle;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
locationTitle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 300, 20)];
[self addSubview:locationTitle];
}
return self;
}
LocationViewController.m
#import "LocationViewController.h"
#import "LocationView.h"
#interface LocationViewController ()
#end
#implementation LocationViewController
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
LocationView *locationView = [[LocationView alloc] initWithFrame:frame];
[self setView:locationView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
How do I pass a value to locationTitle here?
}
You've already set up the locationTitle property for LocationView objects, so you can just access that. The only thing you need to do beforehand is keep a reference to the LocationView object around in an instance variable so you can access it from any instance method.
#implementation LocationViewController {
LocationView *_locationView;
}
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
_locationView = [[LocationView alloc] initWithFrame:frame];
[self setView:_locationView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_locationView.locationTitle = #"Test";
}
#end
Alternatively, since you are assigning the custom view to the view controllers main view, you could cast that:
- (void)viewDidLoad
{
[super viewDidLoad];
((LocationView *)self.view).locationTitle = #"Test";
}

Resources