可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to add few labels on top of an UIImageView
. The labels' text can be changed by tapping on them. What is the best way to achieve this? I am using Swift programming language. Looking up some solutions on stackoverflow, I found a couple of walkthroughs that use String.drawInRect
method to draw some text in a rectangle which is then placed on the UIImageView
. But like this I don't think I will be able to change the text, or even recognize a touch event on them. Please help.
UPDATE
My code so far:
override func viewDidLoad() {
super.viewDidLoad()
let img = UIImage(named: "Image")
let imgView = UIImageView(image: img)
self.view.addSubview(imgView)
var myLabel = UILabel()
myLabel.text = "Hello There"
myLabel.textColor = UIColor.redColor()
myLabel.font = UIFont(name: "Marker Felt", size: 20)
myLabel.accessibilityIdentifier = "this is good!"
myLabel.frame = CGRect(x: img!.size.width/2 /* - myLable.width / 2 ? */, y: 0, width: img!.size.width, height: 40)
imgView.addSubview(myLabel)
imgView.userInteractionEnabled = true
myLabel.userInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: "handlePanGesture:")
myLabel.addGestureRecognizer(tapGesture)
}
func handlePanGesture(sender: UITapGestureRecognizer) {
var senderView = sender.view as! UILabel
print(senderView.text)
senderView.text = "look how i changed!"
print(senderView.accessibilityIdentifier)
}
So far the results are positive I have an image with the label on top of it that can respond to touch events. Now I need to find the label's width so that I can effectively place it in the center when required. Then I need to find a way to place the labels at exact coordinates relative to the image's top left corner as origin.
Any help in these two tasks will be hugely appreciated.
回答1:
Adding label on ImageView
is best approach. but you can also do it by adding button
on ImageView
.
I created a example where i created a ImageView
on storyboard and create its outlet in ViewController class and in viewDidLoad
i created a label and add it to label and add UITapGestureRecognizer
to label. when user taps label we changed the label text and it's position.
class ViewController: UIViewController {
@IBOutlet weak var winterImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(x: 10, y: 0, width: self.winterImageView.frame.width - 10, height: 30))
label.textColor = UIColor.redColor()
label.userInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
label.addGestureRecognizer(tapGesture)
label.text = "Is Winter is coming, My Friend?"
self.winterImageView.addSubview(label)
}
Change label text and position in handleTap
/// handle tap here
func handleTap(sender: UITapGestureRecognizer) {
let senderView = sender.view as! UILabel
senderView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: senderView, attribute: .CenterX, relatedBy: .Equal, toItem: self.winterImageView, attribute: .CenterX, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: senderView, attribute: .CenterY, relatedBy: .Equal, toItem: self.winterImageView, attribute: .CenterY, multiplier: 1, constant: 0).active = true
print(senderView.text)
senderView.text = "Yes!!! Winter is coming, My Friend!!"
}
You can download project from here InteractiveLabel
回答2:
I use CALayers, gesture recognizers, and the hitTest method of the layers. Sample code below:
class ImageView: UIImageView {
let tapGesture = UITapGestureRecognizer()
let redLayer = CATextLayer()
var redHitCounter:Int = 0
let greenLayer = CATextLayer()
var greenHitCounter:Int = 0
override init(frame: CGRect) {
super.init(frame: frame)
setUpClickableLayers()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpClickableLayers()
}
private func setUpClickableLayers() {
self.isUserInteractionEnabled = true
tapGesture.numberOfTapsRequired = 1
tapGesture.addTarget(self, action: #selector(changeText))
self.addGestureRecognizer(tapGesture)
redLayer.frame = CGRect(x: 40, y: 40, width: 100, height: 40)
redLayer.backgroundColor = UIColor.red.cgColor
redLayer.string = String(redHitCounter)
redLayer.alignmentMode = kCAAlignmentCenter
self.layer.addSublayer(redLayer)
greenLayer.frame = CGRect(x: 40, y: 140, width: 100, height: 40)
greenLayer.backgroundColor = UIColor.green.cgColor
greenLayer.string = String(redHitCounter)
greenLayer.alignmentMode = kCAAlignmentCenter
self.layer.addSublayer(greenLayer)
}
internal func changeText(_ recognizer:UITapGestureRecognizer) {
let p = recognizer.location(in: self)
if (redLayer.hitTest(p) != nil) {
redHitCounter += 1
redLayer.string = String(redHitCounter)
} else if (greenLayer.hitTest(p) != nil) {
greenHitCounter += 1
greenLayer.string = String(greenHitCounter)
}
}
}
A few notes:
(1) Remember to set your UIImageView's isUserInteractionEnabled to true. It took me an hour to debug why my UIImageView was seeing gestures!
(2) The hitTest() method works for the CALayer and all subclasses. Just remember to make the layer large enough to work on fat fingers.
(3) You can also use the pan and pinch gestures to move, rotate, and resize the target layer.
回答3:
I can see from the other answers and comments related to one another virtually same stuff.If you familiar using Cocoa pods then you will agree with my opinion.Always,Just look around yourself and pick the best.If you want your project goes smooth and steady then JLStickerTextView is your friend and its way to go.It's free,elegant and more vibrant label customisation project available to everyone and the best thing about this project is written in handy Swift.
Github Link: https://github.com/luiyezheng/JLStickerTextView
Features
- You can add multiple Text to StickerTextView at the same time
- Multiple line Text support
- Rotate, resize the text with one finger
- Set the Color, alpha, font, alignment, TextShadow, lineSpacing...... of the text
- StickerTextView also handle the process of rendering text on Image
Written in Swift
Note: In, My personal opinion.Way, the code been written in this projects simply superb and properly categorised.
Avaliable Text Attributes Reference:
MainView Screenshot from the project:
Output from my personal project based on JLStickerTextView.I, hope you will consider it.If you need any more information let me know...
回答4:
You can use a label and add a gesture recognizer from which you can set an action.
EDIT (responding to OP comment) :
Basically you put an UILabel on top of your card, set a gesture recognizer on it, and set a hidden UITextField at the same position as your label. This way when you tap on it, you specify in your gesture recognizer method that the UI must set label as hidden and textfield as visible. When you're done (end editing), just save your changes and update the UI.
回答5:
If you just want to center align your UILabel and UIImageView, you can use AutoLayout constraint.
NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: imageView, attribute: .CenterX, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: imageView, attribute: .CenterY, multiplier: 1, constant: 0).active = true
回答6:
func handlePanGesture(sender: UITapGestureRecognizer) {
let senderView = sender.view as! UILabel
print(senderView.text)
senderView.textColor = UIColor.redColor()
senderView.text = "look how i changed!"
print(senderView.accessibilityIdentifier)
}
Ouput :
sender.view?.frame
▿ Optional
▿ Some : CGRect
▿ origin : CGPoint
- x : 0.0
- y : 0.0 { ... }
▿ size : CGSize
- width : 335.0
- height : 28.0
回答7:
github.com/khush004/StickerView/tree/master
here is code of JLStickerTextView which is error free with compatibility of swift 3.0