Change textLabel.text without reloading the view? - ios

i have a game, which update method is called every 0.5 seconds. and i have a second method which is called every 2 seconds and should change the text in my Labels:
func changeName(){
textLabel.text = "this is a test, 4 U <3"
textLabel.hidden = false
}
but then all my other views (in VC) are reseting to their original position. i don't know why!
Can anyone please help me??
i tried it with UIViews and it worked perfect, with hiding. But there seems to be a prob with the name changing. Is there a solution?

If what you are saying that the width of your UILabel changes with the text, then I suggest you add constraint on the UILabel's width. If you are using storyboard select the UILabel in the SB and click the lower right icon like in this picture and check width:

Related

Why is UIButton.titleLabel?.text always switching back after I changed it in Swift 5 (UIKit)?

I ran into an issue with my UIButton.
After the User presses the button, it activates an IBAction which is supposed to change the titleLabel.text of my UIButton.
self.btnAppleHealthKit.titleLabel?.text = "Already pressed."
Whenever I press the button, the text changes for about a quarter second to "Already pressed", but switches back immediately to the previous text.
Important Note: The whole thing is inside a completion handler but I wrapped it into DispatchQueue.main.async { }
Can you guys think of an idea why this error appears?
Thanks for your help in advance.
It seems, UIButton does not allow to configure text or color of titleLabel.
From apple doc.s
Do not use the label object to set the text color or the shadow color.
Instead, use the setTitleColor(:for:) and setTitleShadowColor(:for:)
methods of this class to make those changes. To set the actual text of
the label, use setTitle(_:for:) (button.titleLabel.text does not let
you set the text).

VoiceOver reads accessibility label twice when focusing non-UILabel titleView

I'm encountering a strange issue with VoiceOver.
Goals:
Set a UIStackView containing multiple UILabel's as my navigationItem.titleView.
Mark the stack view as an accessibility element and set its accessibilityLabel to an appropriate value.
Set the stack view as the initial VoiceOver focus by calling UIAccessibility.post(notification: .screenChanged, argument: navigationItem.titleView) inside viewDidAppear(animated:).
Expected Result:
When the view controller appears the focus appears to be on the title view and VoiceOver reads the contents of the accessibility label one time.
Actual Result:
VoiceOver starts to read the contents of the accessibility label and then part way through (or sometimes after finishing) it proceeds to read it a second time.
This issue does not occur if I set navigationItem.titleView to an instance of UILabel.
Does anyone know why this happens? Is it a bug in iOS?
I have set up a simple project demonstrating the issue here:
https://github.com/rzulkoski/Focus-TitleView-Bug
The reason why you have a second time reading of your title is in your code.
In your viewDidLoad, you set the stackview accessibility label that VoiceOver automatically reads out to inform the user of the changing.
Next, you notify this changing with a post in your viewDidAppear that VoiceOver naturally reads out as well.
To prevent from this behavior, just delete stackView.accessibilityLabel = label.text in your setupNavigationItem function and add this snippet in your private lazy var label init :
if (self.view.subviews.contains(stackView)) {
stackView.accessibilityLabel = label.text
}
Updating the stackView.accessibilityLabel this way doesn't trigger VoiceOver to inform the user and allows to get your purpose.
However, I don't recommend to read out the title as the first element of a new page unless you reorder the presented elements.
VoiceOver users won't naturally guess that another element is present before the title :
They may not find a way to get back to the previous page.
They may be lost if they get the first element of the page with a 4 fingers simple-tap because they'll get the back button and not the title.
Technically, your problem is solved with the piece of code above but, conceptually, I suggest to reorder your elements if you still want to expose the title as the first element.
==========
EDIT (workaround)
About the technical problem, you're right in your comment, this solution above works thanks to the label reading by VoiceOver.
I commited a solution in your git branch you gave in your initial post.
The problem deals with the UIStackView I cannot explain in this case and cannot solve neither as is.
To reach your purpose, I created a UIAccessibilityELement for the stackview that can be perfectly reached and exposed with no double reading with a postnotification.
I did that because I couldn't get programmatically the stackview new size when the labels are in... maybe creating a UIStackView subclass and get into its layoutSubviews could be the trick ?
This solution should work as a workaround but I don't know the reason why this behavior appears with a UIStackview.
==========
EDIT (solution)
The problem is the way the titleView of the navigationItem is created. The best way to achieve your purpose is to :
Initialize your titleView as a simple UIView whose frame is the same as the stackview's.
Add the stackview as a subview after having specified its frame and its accessibility properties.
Follow the steps hereafter in your code :
Add the .header trait in the stackview property :
private lazy var stackView: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .equalSpacing
stackView.isAccessibilityElement = true
stackView.accessibilityTraits = .header
return stackView
}()
Change the stackview case in your 'switch...case...' code section as below :
case .stackView:
label.text = "UIStackView"
label.sizeToFit()
stackView.addArrangedSubview(label)
label2.text = subtitle
label2.sizeToFit()
stackView.addArrangedSubview(label2)
stackView.frame.size.width = max(label.frame.width, label2.frame.width)
stackView.frame.size.height = label.frame.height + label2.frame.height
stackView.accessibilityLabel = label.text?.appending(", \(label2.text!)")
navigationItem.titleView = UIView(frame: stackView.frame)
navigationItem.titleView?.addSubview(stackView)
}
Now, the postNotification reads out your stackview only once as the first element of your screen.

UIsegmentedControl title appearance

HI, i set my uisegmentedcontrol's width manually, but when the width gets too small, the words becomes ...
Is that anyway that it won't behave in this way? Instead, i just want to show the text just like the picture shown below.
I'd suggest changing your design here and going for a different approach.
The design that you seem to want makes readability pretty much impossible.
Plus, what happens if I'm using your app and add another "Active Project". What happens if I have 10 active projects?
Take the fact that the UI does not work as a sign that you are using the wrong UI for the problem you are trying solve.
I'd suggest possibly just have the current project title here with a button to maybe present a list of projects to switch to... or something.
The text has been truncated. If you want it to fit your segment, you need to update the segment control size based on the text length. If you just want to get rid of truncation, you can use the following snippet. However, it's not recommended, as later Apple might change the UISegmentControl hierarchy.
for item in segmentedControl.subviews {
for subview in item.subviews {
if subview.isKind(of: UILabel.self) {
let _label = subview as! UILabel
_label.numberOfLines = 0
_label.lineBreakMode = .byWordWrapping
}
}
}

iOS - rectangle appears after tapping button

I have two UIButtons and a strange rectangle appears when tapping one of them. I don't know why. I set the images as background images on the button and it worked fine until now.
What I changed now is that I set each button isSelected property and before I did not
Like this:
thumbsDownButton.isSelected = true
thumbsUpButton.isSelected = false
Obviously what I want is for that rectangle to go away
The style was set to System. Setting it to Custom fixed the problem and the rectangle is not appearing anymore. I set it from the xib (if it makes any difference)
Add this Code
thumbsDownButton.tintColor = UIColor.white
It seems your frame may be calculated in the wrong way.
Try to use this one to check it.
button.clipToBounds = true
Please share more code related of initializing and setting up the frame of your view.

How to change labels text from a button on a CCScrollView?

I posted something very similar earlier, but I think the post was confusing so I'm redoing it.
Here's the setup. I am using SpriteBuilder. I have 2 CCB classes, MainScene.ccb and Scroll.ccb. The Scroll.ccb is a layer with a button on it. MainScene contains a CCScrollView and a CCLabelTTF. The CCScrollView is loading Scroll.ccb. The CCScrollView takes up half of the interface of MainScene, and on the other half is a CCColor that has the label on it.
When I click the button on the CCScrollView, I want the label on MainScene to change its text. The problem I am having is that the labels text doesn't change. However if I write an NSLog inside the buttons method to output text in the log, that DOES work.
I am including four pictures to help you better understand the situation.
http://imgur.com/a/77XyJ
I've been stuck on this for over a week now on my main project. I honestly have no clue what to do anymore, I've tried a bunch of things that didn't work, and I've run out of ideas.
EDIT: Okay so I got a little but further in debugging the issue. I inserted a label into the scrollview, and named it Label2. Under the buttons method I added 'Label2.string = #"Test"' and when I ran the program and clicked the button, the label on the scrollview changed. So it seems that when the button is being clicked, it looks in MainScene for the method and finds it, but it can't update a label on a different CCNode.
Do you have linked this method to the "click me" button ? Or maybe try to create a IBAction ?
-(void)testButton {
changeLabel.String = #"Changed !";
}
OR
- (IBAction)testButton:(id)sender {
changeLabel.String = #"Changed !";
}
i mean in your storyboard ( create the link with ctrl key and drag drop )
Hope this will help you.

Resources