Animate letters in a label or text view [closed] - ios

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need to perform an effect like this in my app:
How can I do this? I need to animate single letters in the text and not the entire label. I'm using Swift.
EDIT (more details):
I need to animate the letters from right to left using a sort of spring damping (like UIView animation), but I don't know how to achieve this. The most important part of this animation is the first one, where the letters enter from left to right with a variable space between the first ones and the others

A while back I asked a similar question and got this reply from
https://stackoverflow.com/users/4754400/chris-gulley
A very clever piece of code indeed.
class Timer {
typealias TimerFunction = (Int)->Bool
private var handler: TimerFunction
private var i = 0
init(interval: NSTimeInterval, handler: TimerFunction) {
self.handler = handler
NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: "timerFired:", userInfo: nil, repeats: true)
}
#objc
private func timerFired(timer:NSTimer) {
if !handler(i++) {
timer.invalidate()
}
}
}
class ViewController: UIViewController {
let text: NSAttributedString = {
let font = UIFont(name: "Georgia", size: 18.0) ?? UIFont.systemFontOfSize(18.0)
return NSAttributedString(string: "A long time ago, in a galaxy far, far away ...", attributes: [NSFontAttributeName: font])
}()
override func viewDidLoad() {
super.viewDidLoad()
let textView = UITextView(frame: CGRect(x: 100, y: 120, width: CGRectGetWidth(self.view.frame), height: CGRectGetWidth(self.view.frame)-20))
self.view.addSubview(textView)
let _ = Timer(interval: 0.1) {i -> Bool in
textView.attributedText = self.text.attributedSubstringFromRange(NSRange(location: 0, length: i+1))
return i + 1 < self.text.string.characters.count
}
}
}
Displaying text one character at a time in swift 2.0

Related

Swift: Best way to manage UI elements, such as UIButtons? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm new to Swift.
I'm trying to make template files for all elements that I often use such as buttons and labels.
Can you tell me the best way manage the templates like that has the appearance like including the colors, corner radius?
I cannot figure out except using Class files.
Thanks!
You have 2 ways to do it.
1 - create your own class
final class PrimaryButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = UIColor.red
setTitleColor(UIColor.black, for: .normal)
}
}
2 - create extension to configure
extension UIButton {
func style() {
backgroundColor = R.color.primary()
setTitleColor(R.color.black(), for: .normal)
}
}
and call this function in viewDidLoad
first style is preferred
Personally, I like to create a new file called "Styling" with the same-named class.
Then, inside there, I create static functions that accept parameters that you want to edit (for example, button).
class Styling {
static func styleButton(_ button: UIButton) {
button.layer.cornerRadius = 25.0
}
}
Then I just call it by typing in vc:
Styling.styleButton(myButton)
To add to the above answers what works for me is putting series of buttons in an array of UIButtons. It makes it much simples to rearrange them while developing the app or adjusting to various screens.
Here is a simplified example of 12 buttons forming a colorful flag:
var flagButton: [UIButton] = []
for i in 0...11 {
flagButton.append(UIButton())
flagButton[i].frame = CGRect(x: x, y: y, width: width, height: height)
self.view.addSubview(flagButton[i])
}
You can create a class like this:
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.layer.cornerRadius = 20
}
}
And use it:

Can't Get iOS Print Renderer to Draw Properly

OK. There seems to be a dearth of examples on this, and I am fairly stumped.
I'm trying to make a custom print page renderer; the type that completely customizes the output, not one that uses an existing view.
The really weird thing, is that I was able to do this in ObjC a couple of years ago, and I can't seem to do the same thing in Swift.
I should mention that I am using the prerelease (Beta 5) of Xcode, and Swift 4 (Which has almost no difference at all from Swift 3, in my project).
The project is here.
It's a completely open-source project, so nothing's hidden; however, it's still very much under development, and is a moving target.
This is the page renderer class.
BTW: Ignore the delegate class. I was just thrashing around, trying to figure stuff up. I'm not [yet] planning on doing any delegate stuff.
In particular, my question concerns what's happening here:
override func drawContentForPage(at pageIndex: Int, in contentRect: CGRect) {
let perMeetingHeight: CGFloat = self.printableRect.size.height / CGFloat(self.actualNumberOfMeetingsPerPage)
let startingPoint = max(self.maxMeetingsPerPage * pageIndex, 0)
let endingPointPlusOne = min(self.maxMeetingsPerPage, self.actualNumberOfMeetingsPerPage)
for index in startingPoint..<endingPointPlusOne {
let top = self.printableRect.origin.y + (CGFloat(index) * perMeetingHeight)
let meetingRect = CGRect(x: self.printableRect.origin.x, y: top, width: self.printableRect.size.width, height: perMeetingHeight)
self.drawMeeting(at: index, in: meetingRect)
}
}
and here:
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var top: CGFloat = contentRect.origin.y
let topLabelRect = CGRect(x: contentRect.origin.x, y: 0, width: contentRect.size.width, height: self.meetingNameHeight)
top += self.meetingNameHeight
let meetingNameLabel = UILabel(frame: topLabelRect)
meetingNameLabel.backgroundColor = UIColor.clear
meetingNameLabel.font = UIFont.boldSystemFont(ofSize: 30)
meetingNameLabel.textAlignment = .center
meetingNameLabel.textColor = UIColor.black
meetingNameLabel.text = myMeetingObject.name
meetingNameLabel.draw(topLabelRect)
}
Which is all called from here:
#IBAction override func actionButtonHit(_ sender: Any) {
let sharedPrintController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.general
printInfo.jobName = "print Job"
sharedPrintController.printPageRenderer = BMLT_MeetingSearch_PageRenderer(meetings: self.searchResults)
sharedPrintController.present(from: self.view.frame, in: self.view, animated: false, completionHandler: nil)
}
What's going on, is that everything on a page is being piled at the top. I am trying to print a sequential list of meetings down a page, but they are all getting drawn at the y=0 spot, like so:
This should be a list of meeting names, running down the page.
The way to get here, is to start the app, wait until it's done connecting to the server, then bang the big button. You'll get a list, and press the "Action" button at the top of the screen.
I haven't bothered to go beyond the preview, as that isn't even working. The list is the only one I have wired up right now, and I'm just at the stage of simply printing the meeting names to make sure I have the basic layout right.
Which I obviously don't.
Any ideas?
All right. I figured out what the issue was.
I was trying to do this using UIKit routines, which assume a fairly high-level drawing context. The drawText(in: CGRect) thing was my lightbulb.
I need to do everything using lower-level, context-based drawing, and leave UIKit out of it.
Here's how I implement the drawMeeting routine now (I have changed what I draw to display more relevant information). I'm still working on it, and it will get larger:
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var remainingRect = contentRect
if (1 < self.meetings.count) && (0 == meetingIndex % 2) {
if let drawingContext = UIGraphicsGetCurrentContext() {
drawingContext.setFillColor(UIColor.black.withAlphaComponent(0.075).cgColor)
drawingContext.fill(contentRect)
}
}
var attributes: [NSAttributedStringKey : Any] = [:]
attributes[NSAttributedStringKey.font] = UIFont.italicSystemFont(ofSize: 12)
attributes[NSAttributedStringKey.backgroundColor] = UIColor.clear
attributes[NSAttributedStringKey.foregroundColor] = UIColor.black
let descriptionString = NSAttributedString(string: myMeetingObject.description, attributes: attributes)
let descriptionSize = contentRect.size
var stringRect = descriptionString.boundingRect(with: descriptionSize, options: [NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading], context: nil)
stringRect.origin = contentRect.origin
descriptionString.draw(at: stringRect.origin)
remainingRect.origin.y -= stringRect.size.height
}

How to add something on an image in swift [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have an anatomic picture and on it, I want to print a image like a dot or something when the user taps on the first image (the body) to point out where does it hurts.
I've already read something on UITapGestureRecognizer, but I don't really understood how it works.
Try this:
override func viewDidLoad() {
super.viewDidLoad()
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap))
self.imageView.addGestureRecognizer(gestureRecognizer)
}
#objc func handleTap(tap: UITapGestureRecognizer) {
let circle = UIView()
circle.center = tap.locationInView(imageView)
circle.frame.size = CGSize(width: 30, height: 30)
circle.layer.backgroundColor = UIColor.redColor().CGColor
circle.layer.cornerRadius = 15
imageView.addSubview(circle)
}

Change typing color in Swift TextView [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
How to change the color by pressing typing in TextView?
For example, I type in black, and then press the button of color orange and more print text in orange color, then I press on the black button and print black text?
The studied methods can have the color of all typed text or placeholders etc.
Try this way:
#IBAction func blackButtonClicked(sender: UIButton) {
let attributedText = textView.attributedText
textView.textColor = UIColor.blackColor()
textView.attributedText = attributedText
}
#IBAction func redButtonClicked(sender: UIButton) {
let attributedText = textView.attributedText
textView.textColor = UIColor.redColor()
textView.attributedText = attributedText
}
You can also achieve this by setting the typingAttributes property of the textView, which seems to be a nicer solution:
#IBAction func redButtonClicked() {
textView.typingAttributes[NSForegroundColorAttributeName] = UIColor.redColor()
}
#IBAction func blackButtonClicked() {
textView.typingAttributes[NSForegroundColorAttributeName] = UIColor.blackColor()
}

Get value of tapped UILabel [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
So I am currently creating dynamic labels, and I need to get their value when tapped. I am creating labels number 1 through 10 with a for loop. I then add them to the view along with UITapGestureRecognizer to detect when tapped. What I need to do is get the text of the tapped label. So if I clicked the label with the text of 1, I'd expect to have the 1 returned. Here's what I'm doing to create the label and adding the gesture recognizer.
for number in numbers.characters {
let touch = UITapGestureRecognizer(target:self, action: "numberClicked")
touch.numberOfTapsRequired = 1
let label = UILabel(frame: CGRectMake(CGFloat(x), CGFloat(y1), CGFloat(width), CGFloat(height)))
label.font = label.font.fontWithSize(38)
label.text = String(number)
label.userInteractionEnabled = true
label.addGestureRecognizer(touch)
self.view.addSubview(label)
}
Here's an example of getting the text of the label in your action function. The key change is to add a colon to the name of the tap action, indicating it takes a sender argument. Then you can access the view property of the sender to get at the UILabel itself.
for number in numbers.characters {
// add a colon after "numberClicked" to indicate it takes an argument
let touch = UITapGestureRecognizer(target:self, action: "numberClicked:")
touch.numberOfTapsRequired = 1
let label = UILabel(frame: CGRectMake(CGFloat(x), CGFloat(y1), CGFloat(width), CGFloat(height)))
label.font = label.font.fontWithSize(38)
label.text = String(number)
label.userInteractionEnabled = true
label.addGestureRecognizer(touch)
self.view.addSubview(label)
}
func numberClicked(gesture: UIGestureRecognizer) {
if gesture.state == .Ended {
if let theLabel = (gesture.view as? UILabel)?.text {
print(theLabel) // print the "1"
}
}
}

Resources