Update the value of an NSSlider in realtime - swift

In my swift 3 app, I have an NSSlider that I created like this:
self.myAwesomeSlider = NSSlider(frame:CGRect(x: 10, y: 100, width: 20, height: 300))
self.myAwesomeSlider?.cell = NSSlider()
self.myAwesomeSlider?.maxValue = 127
self.myAwesomeSlider?.target = self
self.myAwesomeSlider?.isContinuous = true
self.view?.addSubview(self.myAwesomeSlider!)
What I want to do now, is (from another function) update the value of this slider in realtime.
I tried to do it very basic like this:
self.myAwesomeSlider?.integerValue = Int(value)
but it doesnt update the dot. What I wish to get is new value gets calculated and dot on slider does move according to the value.
Is this possible?
thank you
Edit
self.myAwesomeSlider?.integerValue = Int(value)
Apparently, this does work, however, I have to click on another application before I see actual change.

myAwesomeSlider.addTarget(self, action: "sliderValueChanged:",
forControlEvents: UIControlEvents.ValueChanged)
func sliderValueChanged() {
var slider = sender as! UISlider
label.text = "\(slider.value)"
}

Related

Swift 3 Marquee Label Notification Before Repeats or At Home Position

I am using Marquee label in Swift 3, its working fine. The only thing is I am having trouble with the following:
I am trying to find out when the label returns to the home position. When the text returns home it is off screen, this is when I would like to update the dataString.
If I try updating the string during the scroll it automatically stops and resets. Also the dataString length is variable so i can't use timers or anything like that.
I have had a read through everything here Marquee Label
This is my code that I'm using to setup and start my label:
feedLabel.text = dataString
feedLabel.type = .continuous
feedLabel.speed = .rate(70)
feedLabel.fadeLength = 80.0
feedLabel.leadingBuffer = 1300.0
feedLabel.trailingBuffer = 1300.0
feedLabel.labelWillBeginScroll()
My dataString updates every few seconds but i only want my label to update just before it repeats.
This has been blowing a hole in my brain. Any suggestions would be greatly appreciated.
You can create new inherited class from MarqueeLabel and override labelReturnedToHome function:
class CustomMarqueLabel : MarqueeLabel {
open var returned : ((Bool)->Void)?
override func labelReturnedToHome(_ finished: Bool) {
super.labelReturnedToHome(finished)
if returned != nil {
returned!(finished)
}
}
}
Then use like this:
let lengthyLabel = CustomMarqueLabel(frame: CGRect(x: 20, y: 40, width: 200, height: 20), duration: 0.5, fadeLength: 10.0)
lengthyLabel.returned = {completed in
//label returned to begining
}

I am trying to create a subclass of UIImageView in swift to add a simple counter

I am trying to create a subclass of a UIImageView so that I can add a simple counter that will be used to decide whether the image flips horizontally or not when tapped. I read the instructions Apple provides for inheritance and it looks to me as if I'm doing it right. I'm sure its something easy.
Here's the attempt:
class flippableImage: UIImageView {
var flipNumber:Int = 0
}
Then I want to be able to change that property when I tap the image. When I go assign flipNumber a value when setting up the object it says that "UIImageView" has no member "flipNumber". Yes, I initialized the subclass and not the parent class. What am I doing?
EDIT to show creation:
let imageChosen = UIImage(named: availableImages[NSUserDefaults.standardUserDefaults().integerForKey("image")])
image = Face(image: imageChosen)
image.frame = CGRect(x: self.view.frame.size.width/2, y: self.view.frame.height/2, width: (faceChosen?.size.width)! * 0.75, height: (faceChosen?.size.height)! * 0.75)
image.userInteractionEnabled = true
image.multipleTouchEnabled = true
backgroundImage.addSubview(image)
backgroundImage.userInteractionEnabled = true
image.center = self.view.center
image.flipNumber = 0 //this doesn't work
Within the ViewController, set each image's tag property to its counter's value.

Swift: Add a label and place it underneath another label

I want to create labels programmatically with text that comes from a database.
So a for loop is creating the labels with this function at the moment:
func fillScrollViewWithLabels() {
for message in messages {
let label = UILabel(frame: CGRectMake(0, 0, 200, 21))
label.text = message.message
self.chatScrollView.addSubview(label)
}
}
But this function puts the labels one above the other.
It should look like a messenger - the labels are the text messages and I think a scrollView is perfect for that.
You will need to make a variable for the Y position of your labels
var currentLabelYPosition : CGFloat = 0 // set to first y position
Then as you iterate through your array and create a label you'll need to get it's Y position based on the last labels Y position, like this:
for message in messages {
let label = UILabel(frame: CGRectMake(0, currentLabelYPosition, 200,21))
label.text = message.message
self.chatScrollView.addSubview(label)
currentLabelYPosition + label.frame.size.height // Update this accordingly with any type of padding, offset, etc.
}
I didn't fully understand your question but you're free to use Scrolview's subclass textview to store texts and than add different text in every message.
I suggest to check this github repo to familiarize concept of chat apps.
Edit
Also found this notification chat github repo much more lightweight sample to examine.
Update your code like this
var yPos:CGFloat = 0.0
let label = UILabel(frame: CGRectMake(0, yPos, 200, 21))
for message in messages {
let label = UILabel(frame: CGRectMake(0, yPos, 200, 21))
label.text = message.message
self.chatScrollView.addSubview(label)
yPos = yPos+21;// you can also add spacing if you want
}

Programmatically place the Cursor inside a textField of a custom tableView header

How can you programmatically make sure that the cursor of a tableView-HeaderView-TextField gets active (i.e. is the first responder) ??
My table looks like this (i.e with the custom TextField header). So far, the cursor only gets inside the grey header field by clicking inside the textfield. But I would like to be able to get the cursor inside the textfield programmatically....
The code for my custom tableview-header looks like this :
// drawing a custom Header-View with a TextField on top of the tableView
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let container = UIView(frame: CGRectMake(0, 0, self.view.frame.size.width, 50))
let textField = UITextField(frame: CGRectMake(10, 15, self.view.frame.size.width/2 - 40, 45))
textField.delegate = self
self.txtfield = textField
textField.textColor = UIColor.blackColor()
let placeholder = NSAttributedString(string: "..add player", attributes: [NSForegroundColorAttributeName: UIColor.darkGrayColor()])
textField.attributedPlaceholder = placeholder
textField.backgroundColor = UIColor.lightGrayColor()
container.addSubview(textField)
var headPlusBttn:UIButton = UIButton.buttonWithType(UIButtonType.ContactAdd) as! UIButton
headPlusBttn.center.x = self.view.frame.size.width - 20
headPlusBttn.center.y = 38
headPlusBttn.enabled = true
headPlusBttn.addTarget(self, action: "addTeam:", forControlEvents: UIControlEvents.TouchUpInside)
container.addSubview(headPlusBttn)
return container
}
My first approach was to set the first-responder of the headerViewForSection like this (see code):
// reload entries
func reloadEntries() {
self.tableView.reloadData()
// the following does unfortunately not work !!!!!
self.tableView.headerViewForSection(1)?.becomeFirstResponder()
}
Not sure why this does not work. Maybe, the Section-Nr (Int=1) is wrong. But I tried several section-numbers. No curser where it should be.
Any help appreciated !
Usually adding a delay helps in situations like this. It allows the OS to do everything it wants with the view, and then it won't mess up what you're trying to do at the same time.
Maybe something like this:
func reloadEntries() {
self.tableView.reloadData()
let delay = (Int64(NSEC_PER_SEC) * 0.1)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, triggerTime), dispatch_get_main_queue(), { () -> Void in
self.tableView.headerViewForSection(1)?.becomeFirstResponder()
})
}
I haven't tested this to do what you want, so you may need to find a different place to put this.
Also, are you sure you want to affect the view in section 1? From your image it looks like you want to mess with the header in section 0.
Be sure to drop into the debugger and check that the header isn't nil. Your code implies that that's a valid condition. You might try writing it like this (at least for testing):
if let header = self.tableView.headerViewForSection(1) {
header.becomeFirstResponder()
}
else {
print("There is no header.")
}
Try
self.tableView.headerViewForSection(1)?.textfield.becomeFirstResponder()

Getting the value from a button

I've got a series of buttons that all contain randomly generated letters (ie. Button one is Z, button 2 is X... and so on). When the user tap on a button, I want to grab the value of that button and create a new label with that value.
This is the code I have now
#IBAction func zeroB(sender : UIButton) {
buttonPress(sender) // highlight the button
var label = UILabel(frame: CGRectMake(0, 0, 250, 50))
label.text = "\(sender.currentTitle))"
label.font = UIFont.systemFontOfSize(26)
letterView.addSubview(label)
}
It creates a label, but the text in the label displays as Optional("Z")).
What am I missing?
I should add that i'm completely new to iOS programming. I'm making an app to teach myself.
Thanks.
Since currentTitle of a UIButton is an optional string, you would be getting the Optional(...) part.
If you know that the title has been set to a non-nil string, use exclamation point to unwrap it:
label.text = "\(sender.currentTitle!))"
This will produce Z) in the label (I am assuming that the extra closing parenthesis is not a typo, and you actually want it in the title of your label). If you do not want the extra parentheses after the title, use
label.text = sender.currentTitle!
current Title is an optional. You can extract the optional in one of two ways:
1)
let labelText = sender.currentTitle!
label.text = labelText
or 2)
if let labelText = sender.currentTitle {
label.text = labelText
}