This is part of my code, in which I add a subview to an UIButton.
self.imageView?.hidden = true
guard self.subviews.contains(frequencyView) else {
print("show frequency view\(self.imageView?.hidden)")
self.addSubview(frequencyView)
print("show frequency view\(self.imageView?.hidden)")
self.imageView?.hidden = true
print("show frequency view\(self.imageView?.hidden)")
return
}
However I when I set the button's imageView.hidden = true before I addSubview. It'll automatically change the hidden state to false.
show frequency viewOptional(true)
show frequency viewOptional(false)
show frequency viewOptional(true)
Is there any method that can prevent it from happening? or do I have to change it back to true after that.
Related
UIButton is programmatically created.
At first, it is shown.
User taps it.
The code programmatically sets its .isHidden to true, but it stays shown.
When set true, next line is print that shows .isHidden is true. (see OUTPUT below)
But I still see it.
HERE IS CODE....................
DispatchQueue.main.async
{
connect_dropbox_UIButton = UIButton(frame: CGRect(x: tap_button_2nd_x,
y: tap_row_y,
width: tap_buttom_width,
height: tap_height ))
connect_dropbox_UIButton.setTitle( "DX", for: .normal )
connect_dropbox_UIButton.addTarget( self, action: #selector( connect_dropbox ), for: .touchUpInside)
connect_dropbox_UIButton.backgroundColor = UIColorFromRGB( rgbValue: 0x0080ff )
connect_dropbox_UIButton.isHidden = is_dropbox_connection( TRUE )
print("show_DX_tap: is_dropbox_connection", is_dropbox_connection() )
print("show_DX_tap: connect_dropbox_UIButton.isHidden", connect_dropbox_UIButton.isHidden ) // shows "true"
connect_dropbox_UIButton.isEnabled = TRUE
self.view.addSubview( connect_dropbox_UIButton )
}
func is_dropbox_connection( _ is_dump: Bool = false ) -> Bool
{
if DBG_UPLOAD || is_dump {
print("is_DROP_1_authorizedClient_successful", is_DROP_1_authorizedClient_successful )
print("is_DROP_2_authorizeFromControllerV2_successful", is_DROP_2_authorizeFromControllerV2_successful )
print("is_DropboxOAuthCompletion", is_DropboxOAuthCompletion )
}
// Abort if no dropbox access before session:
if !is_DROP_1_authorizedClient_successful // DX API access is ok
|| !is_DROP_2_authorizeFromControllerV2_successful // always set TRUE
|| !is_DropboxOAuthCompletion // call back sets TRUE or false
{
return false
}
else
{
return TRUE
}
}
HERE IS OUTPUT.....................
is_DROP_1_authorizedClient_successful true
is_DROP_2_authorizeFromControllerV2_successful true
is_DropboxOAuthCompletion true show_DX_tap: is_dropbox_connection
true show_DX_tap: connect_dropbox_UIButton.isHidden true
I copy pasted your code and changed TRUE to true, and the button was hidden for me.
However, based on the code snippets you posted, the user would never get the chance to interact with the button because you don't add it as a subview until after you already set .isHidden to true. If you are seeing a button, it is either a different button or you are adding and modifying this one somewhere else. I would double check where in your code that happens - the logic in these two code snippets seems to behave the way you intended it to.
A view's height in my view controller needs to change as the user interacts with the application. Sometimes the view needs to be larger in height and other times it needs to be shorter depending on the number of options a user has.
I have implemented a method to change the height depending on the state of the view, and I call this method in viewDidLoad to set the initial state, and I recall the method whenever the state changes.
However, the only time the view actually updates the layout is from the call in viewDidLoad. All other calls of my method do not update the view.
func updateContainerViewHeight(constant: CGFloat) {
print("lets update")
baseView.heightAnchor.constraint(equalToConstant: constant).isActive = true
containerView.heightAnchor.constraint(equalToConstant: constant).isActive = true
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
FYI print("let's update") is printing in the console.
As here
baseView.heightAnchor.constraint(equalToConstant: constant).isActive = true
containerView.heightAnchor.constraint(equalToConstant: constant).isActive = true
every call adds new constraints which will cause conflicts , so create
1-
var baseCon,containCon:NSLayoutConstraint!
2-
baseCon = baseView.heightAnchor.constraint(equalToConstant: constant)
baseCon.isActive = true
containCon = containerView.heightAnchor.constraint(equalToConstant: constant)
containCo.isActive = true
3- Then play with constant
baseCon.constant = ////
I'm developing an iOS application and then the issue that I have faced now is showing a view using the view property isHidden.
I initialized a custom view including a CAAnimation and then set the default isHidden property true to hide. After a certain condition meets I changed the isHidden property to false to show it. But in this case the view doesn't appear.
private func setupButtonEffectView() {
self.buttonEffectView = ButtonEffectView()
self.buttonEffectView!.translatesAutoresizingMaskIntoConstraints = false
// self.view.addSubview(self.buttonEffectView!)
self.view.insertSubview(self.buttonEffectView!, belowSubview: self.button!)
NSLayoutConstraint.activate([
self.buttonEffectView!.centerXAnchor.constraint(equalTo: self.button!.centerXAnchor),
self.buttonEffectView!.centerYAnchor.constraint(equalTo: self.button!.centerYAnchor),
self.buttonEffectView!.widthAnchor.constraint(equalToConstant: 100),
self.buttonEffectView!.heightAnchor.constraint(equalToConstant: 100)
])
self.buttonEffectView!.isHidden = true
}
I created the button effect using the method above.
Try instead of hiding the view, setting the alpha to 0.0. self.buttonEffectView.alpha = 0.0. Then when you want to show it set the alpha to 1.0.
I have this code, that changle constraint based on visibility of element:
if (self.collectionView.isHidden){
controller.view.bottomAnchor.constraint(equalTo: self.collectionView.topAnchor).isActive = false
controller.view.bottomAnchor.constraint(equalTo: self.view2.topAnchor).isActive = true
}
else {
controller.view.bottomAnchor.constraint(equalTo: self.collectionView.topAnchor).isActive = true
controller.view.bottomAnchor.constraint(equalTo: self.view2.topAnchor).isActive = false
}
If I do this after collectionView.isHidden is set to true, it works. However, after I set collectionView.isHidden = true and call this code, it no longer works and controller.view is still attached to the top of view2.
There is also an height constraint attached to collectionView ant ist values is 50.
I also have tried manually setting collectionView.frame.size.height = 50 (or some other default value) because without this, height of collectionView.frame.size.height is zero. But not works. I have tried call collectionView.updateConstraints(), but it has no effect either.
So, I think you are setting a new constraint every time you call the function, you are not really removing the previous one.
Usually when I need this kind of logic I keep a reference to the constraint so that I can activate/deactivate it later, like this:
var controllerBottomAnchor: NSLayoutConstraint?
Then I assign it like so:
controllerBottomAnchor = controller.view.bottomAnchor.constraint(equalTo: self.collectionView.topAnchor)
controllerBottomAnchor?.isActive = true
Once I need to change it I just use the reference:
controllerBottomAnchor?.isActive = false
I typically use it for width and height anchors.
I'm working on an app that is highly dependent on UITextView. My ideal behavior is when a user quickly presses a double space, the text cursor will jump ahead 5 spaces to make space for a UIButton. I've implemented the following code, but the cursor doesn't seem to jump even though all the other actions in the "quickSpace" area happen. Anyone know what I am doing wrong?
UPDATE: I think the problem is that I am trying to jump the cursor to a point outside of the range that currently exists. In other words, someone is entering new text into the UITextView and the range is set to wherever the cursor happens to be. Is that the end of the range? Is it possible to send a cursor outside of the range that currently exists?
if(text==" "){
let now=Date()
if let last=previousSpaceTimestamp
{
if now.timeIntervalSince(last)<0.3
{
//mainTextBox.text=textView.text.appending("hello")
isQuickSpace=true
var checkOffButton: UIButton=createCheckButton()
checkOffButton.backgroundColor=UIColor.green
checkOffButton.frame.size=CGSize(width: 20, height: 20)
//checkOffButton.frame.offsetBy(dx: 0, dy: CGFloat(buttonYPos))
mainTextBox.addSubview(checkOffButton)
buttonYPos=buttonYPos+15
if let currentRange=mainTextBox.selectedTextRange
{
if let newPosition=mainTextBox.position(from: currentRange.start,
offset: 200)
{
mainTextBox.selectedTextRange=mainTextBox.textRange(from: newPosition,
to: newPosition)
}
}
return false
}
}
previousSpaceTimestamp=now
}
else
{
previousSpaceTimestamp=nil
}
return true
}
Set the TextView Range Like this in Main Queue.
DispatchQueue.main.async {
mainTextBox.isEditable = true
mainTextBox.selectedRange = NSMakeRange(2, 0)
}