I am using a UIView not a view controller/ I am removing the view once the delete button is clicked. I am trying to make the view come back when a user wants the view back.
example : myView.removeFromSuperview()
Is there anyway to bring the view back?
In swift thank you guys!
#IBOutlet weak var brokeView: UIView!
#IBOutlet weak var deleteButton: UIButton!
#IBAction func deleteViewButton(sender: AnyObject) {
if brokeView != nil {
brokeView.removeFromSuperview()
}
#IBOutlet weak var brokeView: UIView!
you already have a reference to the view brokeView which you are going to remove and add again, but its weak so it will be deallocated once it is removed from superView. Since you need this brokeView to add back make it strong.
#IBOutlet var brokeView: UIView!
Now you can add it back like
view.addSubview(brokeView)
No, there is no way to get it back unless you initialise it again. You can hide the view and unhide it.
viewToBeHidden.hidden = true
//when you want to make it reappear unhide it.
viewToBeHidden.hidden = false
Or like #rmaddy suggested keep the reference.
var myView = UIView()
myView.removeFromSuperview
//then just add it back.
self.view.addSubView(myView)
if you removing it from superview, you can add it again, but you should not make that view as nil other wise you will have to create new one.Removing from superview only remove view from parent view.
subview.removeFromSuperview() // remove from parent view
parentView.addSubview(subview) //adding again on it parent view
Create a View:
This sample, it depends on your view which init method, you have created, used that one.
MyCustomView *customView = MyCustomView(frame: CGRectZero(top: 0, left: 0, width: 200, height: 50)
self.view.addSubview(customView)
If you want to use IBoutlet you need to remove weak from your IBoutlet after you remove weak you remove and add the view again to your view but you need to set the constraints programmatically to view.
Example:
// removed 'weak' reference
#IBOutlet var mButton: UIButton!
... other functionality
// remove from superview
mButton.removeFromSuperview()
// add again to view
view.addSubview(mButton)
// set re-set constraints
NSLayoutConstraint.activate([
mButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
mButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -40)
])
Related
OK, so here's the relevant bit of my code:
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var questionView: QuestionView!
#IBOutlet weak var answerView: AnswerView!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint! // Active at start, attaches tableView.topAnchor to questionView.bottomAnchor
#IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint! // Inactive at start, attaches tableView.topAnchor to answerView.bottomAnchor
func submitAnswer() {
tableViewTopConstraint.isActive = false
tableViewTopAlternateConstraint = true
}
func newQuestion() {
tableViewTopConstraint.isActive = true
tableViewTopAlternateConstraint = false
}
}
I'm building a question/answer type of app and the two subviews are different sizes for design reasons. I have it set so that it toggles between the two subviews depending on the current state (toggling back for a new question when the user taps to advance), and it works fine...
...until I go to a different tab on the UITabView that encloses everything (e.g. to change the settings then resume testing)
The moment the tab changes it's like the NSLayoutConstraint outlets no longer exist. The orders to change them still process (I've verified this in the console), but they do nothing.
I've tried declaring the outlets as strong (there was no difference in behavior)
I've removed the outlets and managed them in code (it worked the first time, but afterward it stretched the shorter QuestionView's height to match tableView's new top position instead of moving tableView up to the bottom of QuestionView as was intended)
I've tried implementing a UITabViewController so that I could call tabBar(_:didSelect:) and replace the view controller with a brand new instance of MyViewController() whenever I switch back to that tab (It loads the first time, but when I try to switch tabs it finds nil when accessing any of the IBOutlets...even though I didn't tap on the tab for the testing view and filtered by item.tag when replacing the existing view controller)
Any suggestions on how else to attack this problem?
First, don't set #IBOutlet properties to weak. I know that's the default, but it's not correct.
If you have this:
#IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint!
connected to a constraint via Storyboard, and you do this:
tableViewTopAlternateConstraint.isActive = false
you just removed that constraint from existence.
In addition, if you have two different Top constraints in Storyboard, you should be getting an Error indicator as they cannot be satisfied.
Better to either change the Priorities, or use a single constraint and change the .constant value.
So, two constraints in Storyboard:
set the "default" constraint to Priority: High (750)
set the "alternate" constraint to PriorityL Low (250)
and your code becomes:
func submitAnswer() {
tableViewTopConstraint.priority = .defaultLow
tableViewTopAlternateConstraint.priority = .defaultHigh
}
func newQuestion() {
tableViewTopAlternateConstraint.priority = .defaultLow
tableViewTopConstraint.priority = .defaultHigh
}
#IBOutlet weak var result: UILabel!
#IBOutlet weak var testview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
testview.layer.shadowColor = UIColor.systemGray.cgColor
testview.layer.shadowOpacity = 0.6
testview.layer.shadowOffset = .zero
testview.layer.shadowRadius = 5
testview.layer.shadowPath = UIBezierPath(rect: testview.bounds).cgPath
testview.layer.shouldRasterize = true
testview.layer.rasterizationScale = UIScreen.main.scale
testview.addSubview(result)
}
After I add result to testview as a subview it's disappeared.
Your Storyboard already added result into the view hierarchy so when you add it again the frame stays the same but the point of reference changes since the superview is now testView so in your case it's going beyond the visible bounds. If you want the UILabel to be a subview of the testView I'd recommend making that change directly on the Storyboard, creating the UILabel programmatically instead of using Storyboards/IBOutlets or updating the frame of the label after adding it to testView.
My two IBoutlet of two views are there which i am trying to flip. After UIView.transition, "from" IBOutlet sets to nil, unable to figure out the reason behind this.
#IBOutlet weak var showingSideView: shadowView!
#IBOutlet weak var hiddenSideView: shadowView!
UIView.transition(from: showingSideView, to: hiddenSideView, duration: 0.7, options: transitionDirection) { (isFlipped) in
self.showingBack = !self.showingBack
}
That is because your view in "from" will be removed from its superview after the transition finishes.
Read more in the docs
As you defined your outlet as weak, there is no retaining object anymore so it gets deallocated.
If you read through the documentation :
By default, the view in fromView is replaced in the view hierarchy by the view in toView. If both views are already part of your view hierarchy, you can include the showHideTransitionViews option in the options parameter to simply hide or show them.
So, to keep your views in the hierarchy, add that option:
#IBOutlet var showingSideView: shadowView!
#IBOutlet var hiddenSideView: shadowView!
UIView.transition(from: showingSideView,
to: hiddenSideView,
duration: 0.7,
options: [.transitionFlipFromLeft, .showHideTransitionViews])
{ (isFlipped) in
self.showingBack = !self.showingBack
}
Edit:
Just for clarification...
Apple now recommends NOT using weak for #IBOutlets, but that has no effect on the problem here. When using .showHideTransitionViews the reference will not become nil even if the #IBOutlets are set to weak.
I have a bottomView with opacity set to 0.65, and embedded in that View I have 5 buttons - which also gets the 0.65 opacity attribute - but How do I make the buttons get rid of the opacity?
I want the buttons to be very clear
I have tried to make outlets of the View and the Buttons and set the buttons to the front - view, but it doesn't change the appearance of the button??
#IBOutlet weak var bottomView: UIView!
#IBOutlet weak var findVejOutlet: UIButton!
#IBOutlet var superViewOutlet: UIView!
#IBAction func findVejButton(_ sender: Any) {
superViewOutlet.bringSubview(toFront: findVejOutlet)
}
override func viewDidLoad() {
super.viewDidLoad()
settingView()
}
func settingView(){
bottomView.bringSubview(toFront: findVejOutlet)
}
If you set the opacity of a view to a value of less than 1, it makes all the contents of a view partly transparent (including subviews). You can't change that, and opacity has nothing to do with the front-to-back ordering of the views.
You either need to make the parent view fully opaque and the non-button subviews partly transparent, or remove the buttons from the translucent view and instead put them in the common parent view.
I'm trying to reorder an image and a stackview (here called labelsStack) that are both contained in another stackview (here called stack). My goald would be to programatically reverse the index order of both subviews in order to change their postition at runtime (they are horizontally distributed, so theorically, if I reorder their indexes, it should reorder them in autolayout)
I have tried to update indexes, exchange subviews, sendViewForward etc from the Apple doc, but it doesn t work, here s the code of my tableViewCell :
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func layoutSubviews() {
cellImage.layer.cornerRadius = cellImage.bounds.height / 3
cellImage.clipsToBounds = true
if incoming {
} else {
// as one of the many methods that didn't work
self.stack.insertSubview(cellImage, belowSubview: labelsStack)
}
}
You could create two alternative sets of constraints, one for the default order and the other for the inverse order. The default constraints are the one ending in 1
To initially deactivate the alternative setting you can use the inspector and change the installed checkbox
Your view controller should now have 6 outlets:
#IBOutlet weak var topViewTopConstraint1: NSLayoutConstraint!
#IBOutlet weak var bottomViewTopConstraint1: NSLayoutConstraint!
#IBOutlet weak var bottomViewBottomConstraint1: NSLayoutConstraint!
#IBOutlet weak var topViewTopConstraint2: NSLayoutConstraint!
#IBOutlet weak var bottomViewTopConstraint2: NSLayoutConstraint!
#IBOutlet weak var topViewBottomConstraint2: NSLayoutConstraint!
now to activate the other set of constraints you can use:
self.topViewBottomConstraint2.active = true
self.topViewTopConstraint2.active = true
self.bottomViewTopConstraint2.active = true
self.topViewTopConstraint1.active = false
self.bottomViewBottomConstraint1.active = false
self.bottomViewTopConstraint1.active = false
and viceversa