How to add UIButton on WKWebview? - ios

I have two viewcontrollers which the viewcontroller1 has a NSTimer countdown to 0 and present viewcontroller2.
The viewcontroller2 has a wkwebview, and I also want to add UIButton on it.
Because I want to create a close button to dismiss viewcontroller2.
I try adding the UIButton on wkwebview, but I can't control it's NSlayoutConstrain.
What's wrong with my code?
Thanks.
red button is on right bottom.
// ViewController1.m
-(void)timerFired {
NSLog(#"===) self.count : %d", self.count);
if (self.count == 0) {
[self.timer invalidate];
self.timer = nil;
ViewController2 *vc = [[ViewController2 alloc] init];
[self presentViewController:vc animated:YES completion:nil];
} else {
self.count -= 1;
}
}
// ViewController2.m
#import "ViewController2.h"
#import <WebKit/WebKit.h>
#interface ViewController2 ()<WKScriptMessageHandler, WKNavigationDelegate,WKUIDelegate>
#property (nonatomic,strong) WKWebView* webView;
#property (nonatomic,strong) UIButton* button;
#property (nonatomic, strong) WKWebViewConfiguration * webConfig;
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:[self createWKWebApp]];
[self.view addSubview: self.webView];
[self.webView.configuration.preferences setValue:#YES forKey:#"allowFileAccessFromFileURLs"];
self.webView.scrollView.bounces = NO;
[self.webView setContentMode:UIViewContentModeScaleAspectFit];
self.webView.navigationDelegate = self;
self.webView.UIDelegate = self;
NSURL *url = [NSURL URLWithString:#"https://stackoverflow.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
self.button = [UIButton buttonWithType: UIButtonTypeCustom];
self.button.translatesAutoresizingMaskIntoConstraints = false;
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:#"CLOSE" forState:UIControlStateNormal];
[self.button addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.button];
NSLayoutConstraint *btnRight = [NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20.0];
NSLayoutConstraint *btnTop = [NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20.0];
NSLayoutConstraint *btnWidth = [NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant:30.0];
NSLayoutConstraint *btnHeight = [NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:30.0];
[self.view addConstraints:#[btnRight, btnTop, btnWidth, btnHeight]];
}
- (void)btnClicked:(UIButton *)sender {
NSLog(#"BTN CLICKED");
[self dismissViewControllerAnimated:false completion:nil];
}
- (WKWebViewConfiguration *)createWKWebApp {
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userContent = [[WKUserContentController alloc] init];
config.userContentController = userContent;
return config;
}
- (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message {
NSString *name = message.name;
NSLog(#"===) message name = %#",name);
NSLog(#"===) body class = %#",[message.body class]);
}

You should konw the constraint like this
item1.attribute1 = multiplier × item2.attribute2 + constant
So the right constraint constant should be -20
NSLayoutConstraint *btnRight = [NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20.0];

It might help you. Use these methods.
-(void)view.sendSubviewToBack(subview)
-(void)view.bringSubviewToFront(subview)
Usage:
[self.view sendSubviewToBack:webview];
[self.view bringSubviewToFront:button];

Related

Change Frame of Subview in Superview

I have a ViewController that adds an UIView, SpeciesImageView as a subview in viewDidLoad and set constraints in viewWillLayoutSubviews.
SpeciesImageView does not have a nib file. When we create speciesImageView in viewDidLoad, it calls initWithFrame in SpeciesImageView class.
This works fine (in both landscape and portrait) until the phone rotates. I tried setting the constraints as speciesImageView.frame.size.width, but that doesn't work because initWithFrame isn't called when the orientation changes, so the height/width of the speciesImageView remains unchanged.
On the other hand, using screenRect doesn't change the actual size of the UIView, it changes its size within the superview. So in other words, I haven't found a way to change the size of the actual speciesImageView on orientation change.
And for reasons lost to me, it gets completely messed up when you rotate it back to the original position.
- (void)viewDidLoad
{
self.tabBarController.tabBar.hidden=YES;
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.hidden = NO;
//self.navigationController.navigationBar.translucent = YES;
UIImage *plantinfo;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
plantinfo = [UIImage imageNamed:#"plantinfo_frame.png"];
} else {
plantinfo = [UIImage imageNamed:#"plantinfo.png"];
}
UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:plantinfo
style:UIBarButtonItemStylePlain
target:self
action:#selector(toggleText:)];
self.navigationItem.rightBarButtonItem = tempButton;
[tempButton release];
self.title = theSpecies.scientificName;
//[self.navigationItem.backBarButtonItem setTitle:#""];
self.navigationItem.backBarButtonItem.title = #"";
infoViewSegmentedControl.backgroundColor = [UIColor blackColor];
webView.backgroundColor = [UIColor blackColor];
_activityIndicator.hidden = YES;
[webView setOpaque:YES];
webView.delegate = self;
// Do double justification
[webView loadHTMLString:[self formatHTML:theSpecies] baseURL:nil];
showingInfoView = NO;
//
// Resize containerView, infoview according to iphone 5 screen size.
//
infoView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
CGPoint screenOrigin = [[UIScreen mainScreen] bounds].origin;
CGSize viewSize = [[UIScreen mainScreen] bounds].size;
CGPoint origin = infoView.frame.origin;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y + statusBarFrame.size.height,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height)];
} else {
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - statusBarFrame.size.height)];
}
speciesImageView.delegate = self;
[containerView addSubview:speciesImageView];
managedObjectContext = [(LeafletAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
[self parseImageURLArray];
}
-(void)viewWillLayoutSubviews{
if(speciesImageView.window != nil){
CGRect screenRect = [[UIScreen mainScreen] bounds];
speciesImageView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0];
[self.view addConstraints:#[widthConst, heightConst, bottomConstraint, rightConstraint]];
}
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
imageScrollView = [[UIScrollView alloc] initWithFrame:frame];
imageScrollView.delegate = self;
imageScrollView.backgroundColor = [UIColor blackColor];
[self addSubview:imageScrollView];
imageScrollView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0];
[self addConstraints:#[widthConst, heightConst, bottomConstraint, rightConstraint]];
}
return self;
}
If you want your views to adjust to the size of the superview,
then you need something like this (set the margin to whatever you like):
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:#"|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:#{#"speciesImageView": speciesImageView}]];
NSString * visualFormatV = [NSString stringWithFormat:#"V:|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:#{#"speciesImageView": speciesImageView}]];
Now speciesImageView will adjust its frame whenever the superview frame changes.
Here is a generic example:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView * sampleView = [UIView new];
sampleView.backgroundColor = [UIColor redColor];
sampleView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:sampleView];
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:#"|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:#{#"sampleView": sampleView}]];
NSString * visualFormatV = [NSString stringWithFormat:#"V:|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:#{#"sampleView": sampleView}]];
}
Auto Layout Getting Started
Auto Layout Visual Format Documentation

Methods for datasource are not called for this custom view

I would like to implement this sort of thing :
1- So first, I have implemented this view : UnitSliderView :
using this code :
#import "UnitSliderView.h"
#implementation UnitSliderView
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
//initialization
self.backgroundColor = [UIColor grayColor];
[self initViews];
[self initConstraints];
}
return self;
}
-(void)initViews
{
_leftLabel = [[UILabel alloc] init];
_leftLabel.textColor = [UIColor whiteColor];
//self.leftLabel.text = #"John";
[self addSubview:_leftLabel];
_rightLabel = [[UILabel alloc] init];
_rightLabel.textColor = [UIColor whiteColor];
//self.rightLabel.text = #"20%";
[self addSubview:self.rightLabel];
_slider = [[UISlider alloc] init];
_slider.value = 0.6;
[self addSubview:_slider];
}
-(void)initConstraints
{
self.rightLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.leftLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.slider.translatesAutoresizingMaskIntoConstraints = NO;
id views = #{
#"leftLabel": self.leftLabel,
#"slider": self.slider,
#"rightLabel": self.rightLabel,
};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[leftLabel(==90)]-5-[slider(==120)]-[rightLabel(==50)]-|" options:0 metrics:nil views:views]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.leftLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.rightLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
}
#end
2- Then, I have created this view, named MultiSliderView, which use the precedent View (UnitSliderView):
#import "MultiSliderView.h"
#import "UnitSliderView.h"
static const int kUnitsCount = 3;
#implementation MultiSliderView
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
//initialization
self.backgroundColor = [UIColor clearColor];
[self initViews];
}
return self;
}
- (void)initViews {
float totalHeight = self.frame.size.height;
float spacingRatio = 0.1;
float heightPerUnit = totalHeight/(kUnitsCount+spacingRatio*(kUnitsCount));
for (int i = 0; i < kUnitsCount; i++)
{
double percentage = [self.dataSource valueForSliderAtIndex:i];
NSString *leftString = [self.dataSource stringForLeftLabelAtIndex:i];
NSString *rightString = [self.dataSource stringForRightLabelAtIndex:i];
UnitSliderView *unit = [[UnitSliderView alloc] initWithFrame:CGRectMake(0, i*heightPerUnit + (i)*heightPerUnit*spacingRatio, self.frame.size.width, heightPerUnit)];
unit.slider.value = percentage;
unit.leftLabel.text = leftString;
unit.rightLabel.text = rightString;
[self addSubview:unit];
}
}
#end
3 - problem : when I init a MultiSlidersView in a viewController, the datasource methods that I have implemented in this same view controller are not called, thus the labels are not shown, and the slider values are 0.
I think there some of my code is not in the right place, but I can't find how to do it differently.
You should define the dataSource of the created class before you call the init function. You should define a method initWithFrame:(CGRect)frame andDataSource:(id <MultiSliderViewDataSource> ) dataSource and use it to initialize your view.
I assume you want to get an action called whenever the slide value changes. Since you implemented everything in code, you can do this in code using e.g.
[youSlider addTarget:self action:#selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];

Positioning UIButtons at top of Screen

What I want is to have 5 buttons equally spaced out at the top of the screen. I tried using constraints but the buttons would get squished.
I have this code so far:
- (void)viewDidLoad {
[super viewDidLoad];
//I know this is only two buttons
NSUInteger space = (_backround.frame.size.width - _squareOne.frame.size.width * 5) / 6;
CGRect newFrameOne;
newFrameOne = CGRectMake(space, 50, 55, 55);
CGRect newFrameTwo;
newFrameTwo = CGRectMake(space * 2 + _squareOne.frame.size.width, 50, 55, 55);
_squareOne.frame = newFrameOne;
_squareTwo.frame = newFrameTwo;
}
The buttons never show up... and I don't know any other ways to do this...
Any help?
Could you try something like this below?
Update: I've written the code properly using Xcode this time (previously I typed it from memory).
See below screenshot for the final result.
View Controller Header File
#interface ViewController : UIViewController
#property (nonatomic, strong) UIButton *btn1;
#property (nonatomic, strong) UIButton *btn2;
#property (nonatomic, strong) UIButton *btn3;
#property (nonatomic, strong) UIButton *btn4;
#property (nonatomic, strong) UIButton *btn5;
#end
View Controller Implementation File
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initViews];
[self initConstraints];
}
-(void)initViews
{
self.btn1 = [[UIButton alloc] init];
self.btn1.backgroundColor = [UIColor grayColor];
self.btn2 = [[UIButton alloc] init];
self.btn2.backgroundColor = [UIColor grayColor];
self.btn3 = [[UIButton alloc] init];
self.btn3.backgroundColor = [UIColor grayColor];
self.btn4 = [[UIButton alloc] init];
self.btn4.backgroundColor = [UIColor grayColor];
self.btn5 = [[UIButton alloc] init];
self.btn5.backgroundColor = [UIColor grayColor];
[self.view addSubview:self.btn1];
[self.view addSubview:self.btn2];
[self.view addSubview:self.btn3];
[self.view addSubview:self.btn4];
[self.view addSubview:self.btn5];
}
-(void)initConstraints
{
self.btn1.translatesAutoresizingMaskIntoConstraints = NO;
self.btn2.translatesAutoresizingMaskIntoConstraints = NO;
self.btn3.translatesAutoresizingMaskIntoConstraints = NO;
self.btn4.translatesAutoresizingMaskIntoConstraints = NO;
self.btn5.translatesAutoresizingMaskIntoConstraints = NO;
id views = #{
#"btn1": self.btn1,
#"btn2": self.btn2,
#"btn3": self.btn3,
#"btn4": self.btn4,
#"btn5": self.btn5
};
// horizontal constraints
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-5-[btn1]-5-[btn2(==btn1)]-5-[btn3(==btn1)]-5-[btn4(==btn1)]-5-[btn5(==btn1)]-5-|" options:0 metrics:nil views:views]];
// vertical constraints
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.btn1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:5.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.btn2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.btn1 attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.btn3 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.btn1 attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.btn4 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.btn1 attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.btn5 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.btn1 attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
}
Result
This is what I get.
What long black strip are you referring to, the battery indicator?

Custom UIView Subclass background color not being set with Autolayout enabled

I am creating a subclass of UIView with AutoLayout and cannot get it's background color to change for the life of me. Can someone take a look at the simple code and verify I am doing everything that needs to be done in the subclass of the UIView(PCCGenericRatingView). I read on SO that setting the background color only works if the frame is set. Shouldn't it be setting my frame to something other than CGRectZero after evaluating the constraints? I am printing out the view's frame in the viewDidAppear: lifecycle method, but it appears to be CGRectZero.
Edit:
When the frame is passed in to the views initWithFrame initializer, the background color is shown. Otherwise, it is now shown.
PCCGenericRatingView.h file:
#import <UIKit/UIKit.h>
#interface PCCGenericRatingView : UIView
#property (nonatomic, strong) UILabel *titleLabel;
#property (nonatomic, strong) UILabel *messageLabel;
- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message;
+ (instancetype)genericRatingViewWithTitle:(NSString *)title andMessage:(NSString *)message;
#end
PCCGenericRatingView.m file:
#import "PCCGenericRatingView.h"
#implementation PCCGenericRatingView
- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message {
if (self = [super init]) {
self.titleLabel = [[UILabel alloc] init];
self.messageLabel = [[UILabel alloc] init];
_titleLabel.text = title;
_messageLabel.text = message;
[self customizeView];
}
return self;
}
- (void)customizeView {
[self addSubview:_titleLabel];
[self addSubview:_messageLabel];
[_titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[_messageLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[_titleLabel setBackgroundColor:[UIColor yellowColor]];
[_messageLabel setBackgroundColor:[UIColor yellowColor]];
[_messageLabel setNumberOfLines:0];
[_messageLabel setTextAlignment:NSTextAlignmentCenter];
[_titleLabel setTextAlignment:NSTextAlignmentCenter];
[_titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f]];
[_messageLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Thin" size:18.0f]];
}
+ (instancetype)genericRatingViewWithTitle:(NSString *)title andMessage:(NSString *)message {
return [[PCCGenericRatingView alloc] initWithTitle:title andMessage:message];
}
+ (BOOL)requiresConstraintBasedLayout {
return YES;
}
- (BOOL)translatesAutoresizingMaskIntoConstraints {
return NO;
}
-(void)updateConstraints {
CGRect windowRect = [UIScreen mainScreen].bounds;
NSDictionary *metrics = #{
#"height" : #(windowRect.size.height),
#"width" : #(windowRect.size.width)
};
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[self(==width)]" options:0 metrics:metrics views:viewsDictionary]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[self(==height)]" options:0 metrics:metrics views:viewsDictionary]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0f
constant:35.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:30.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:-40.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:50.0f]];
[super updateConstraints];
}
#end
Parent View Controller:
#import "PCCLeaveRatingViewController.h"
#import "PCCGenericRating.h"
#import "PCCSliderRatingView.h"
#interface PCCLeaveRatingViewController ()
#end
#implementation PCCLeaveRatingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = #[ [[PCCGenericRating alloc] initWithTitle:#"Easiness"
andMessage:#"WHAT A JOKERRRR"
andVariatons:#[ #"very easy", #"easy", #"moderate", #"hard", #"very hard"]],
];
[self initView];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)initView {
[self setupConstraints];
[self addViewController];
}
- (void)setupConstraints {
CGRect windowFrame = [[UIApplication sharedApplication].delegate window].frame;
CGFloat windowWidth = windowFrame.size.width * self.dataSource.count;
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.containerView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:windowWidth]];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.containerView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:windowFrame.size.height]];
}
- (void)addViewController {
PCCGenericRating *rating = self.dataSource[0];
PCCGenericRatingView *view = [PCCGenericRatingView genericRatingViewWithTitle:rating.title andMessage:rating.message];
[view setBackgroundColor:[UIColor yellowColor]];
const CGFloat viewWidth = [UIScreen mainScreen].bounds.size.width;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view);
NSDictionary *metrics = #{ #"viewWidth" : #(viewWidth) };
[_containerView addSubview:view];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[view(==viewWidth)]" options:0 metrics:metrics views:viewsDictionary]];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:viewsDictionary]];
}
#end
print out the view property to trace whether it is pointing the view which you are referring or other [view setBackgroundColor:[UIColor yellowColor]]

Can't remove/hide recently added view from self.navigationcontroller.view

I have a Navigationviewcontroller with a tableview in it. I am adding a UIView to self.navigationcontroller.view and constraints for Auto Layout. When I try to remove it from superview or to hide it, nothing happens.
Any ideas?
How I create the View and Constraints
-(void)doneWithTraining{
//Create Backgroundview
UIView *groupView = [[UIView alloc] init];
[groupView setTranslatesAutoresizingMaskIntoConstraints:NO];
groupView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
groupView.tag = 999;
groupView.alpha = 0.0;
[self.navigationController.view addSubview:groupView];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0f]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeHeight
}
multiplier:1.0
constant:0.0]];
//Animate View
[UIView animateWithDuration:0.2 animations:^(void) {
groupView.alpha = 1.0;
}];
How I try to remove the View
- (void)closeFinishAlert{
UIView *grouView = [self.navigationController.view viewWithTag:999];
grouView.hidden = YES;
NSLog(#"Check if closeFinishAlert is called");
//[self.navigationController popViewControllerAnimated:YES];
}
What I also tried
This removes the view an its content, but after this there is no user interaction possible. It looks like a crash, but Xcode tells me that the app is still running.
- (void)closeFinishAlert{
UIView *groupView = [self.navigationController.view viewWithTag:999];
for (UIView *subview in groupView.subviews) {
subview.hidden = YES;
[subview removeFromSuperview];
}
[_groupView removeFromSuperview];
//[self.navigationController popViewControllerAnimated:YES];
}
If you are actually just presenting a view which you will remove for sure later on,
then its better to create a ViewController class for your view and present it modally using :
[self presentViewController:yourViewControllerObject animated:NO completion:nil];
you can later on remove this view using:
[self dismissViewControllerAnimated:NO completion:nil];
hope this helps !
Thanks to "GoGreen" green I found a solution which works for me.
Create Viewcontroller from ViewDidAppear
- (void)viewDidAppear:(BOOL)animated{
if (executedExercises.count == [_fetchedResultsController.fetchedObjects count] && self.groupView == FALSE) {
[self performSelector:#selector(doneWithTraining) withObject:nil afterDelay:0.0];
}
}
Header file
#property (strong, nonatomic) UIViewController *groupView;
Creating the Viewcrontroller and its content
-(void)doneWithTraining{
_groupView = [[UIViewController alloc] init];
[self presentViewController:_groupView animated:YES completion:nil];
_groupView.view.backgroundColor = [UIColor whiteColor];
//SubTitle
UILabel *subTitleLabel = [[UILabel alloc] init];
[subTitleLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:18.0]];
subTitleLabel.textColor = [BackgroundLayer gray];
[subTitleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
subTitleLabel.numberOfLines = 5;
subTitleLabel.adjustsFontSizeToFitWidth = YES;
subTitleLabel.textAlignment = NSTextAlignmentCenter;
[_groupView.view addSubview:subTitleLabel];
subTitleLabel.text = subTitleText;
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationLessThanOrEqual
toItem:_groupView.view
attribute:NSLayoutAttributeWidth
multiplier:0.0
constant:300.0f]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeHeight
multiplier:0.0
constant:140]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];}
Removing ViewController
- (void)closeFinishAlert{
[_groupView dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popViewControllerAnimated:YES];
}

Resources