create an equal space between labels in the scrollview with swift - swift

I am creating a menu of the same style as the kiosk play Application
I would like the same space between labels, for I dynamically creates, I try SEVERAL way but it does not work.
I size of their label and I added the padding but it does work.
Here is the result
here is my code
func menu (value: [String]){
var pos: CGFloat = 50.0
var index: Int = 0
for index = 0; index < value.count ; index++ {
self.titleLabel = UILabel()
self.titleLabel.text = "\(value[index])"
self.titleLabel.textColor = UIColor.blackColor()
self.titleLabel.backgroundColor = UIColor.blueColor()
self.titleLabel.font = UIFont(name: "MarkerFelt-Wide", size: 20)
self.titleLabel.sizeToFit()
//width of the label
var widhtLabel = self.titleLabel.frame.size.width
// add padding
self.titleLabel.frame.origin.x = widhtLabel + pos
self.scrollViewMenu.addSubview(self.titleLabel)
pos += 150.0
println()
}
self.scrollViewMenu.contentSize = CGSize(width: self.titleLabel.frame.origin.x + 220, height:0)
}
thanks

Related

Not deleting label subview in view (swift)

I am dynamically adding labels to the screen. I add outline text to this label.
When I create 2 labels, when I zoom in the first label, the outline text is not deleted and regenerated. I give different tags to each label and outline text. Outline text is tag => label tags + 1
Why isn't this outline text deleted even though there are different tags?
Outline text extension
`
extension UILabel {
func addTextOutline(usingColor outlineColor: UIColor, outlineWidth: CGFloat, tagX: Int) {
let textOutline = OutlinedText()
let outlineTag = tagX + 1
print("label_tag_outline: \(outlineTag) ")
print("label_tag_outline_self: \(tag) ")
// label tag :955182
if let prevTextOutline = viewWithTag(outlineTag) {
prevTextOutline.removeFromSuperview()
print("label_tag_outline: \(outlineTag) delete **************")
}
textOutline.outlineColor = outlineColor
textOutline.outlineWidth = outlineWidth
textOutline.textColor = textColor
textOutline.font = font
textOutline.text = text
textOutline.tag = outlineTag
sizeToFit()
addSubview(textOutline)
textOutline.frame = CGRect(x: -(outlineWidth / 2), y: -(outlineWidth / 2),
width: bounds.width + outlineWidth,
height: bounds.height + outlineWidth)
// MARK: - - OutlinedText CLASSS
class OutlinedText: UILabel {
var outlineWidth: CGFloat = 0
var outlineColor: UIColor = .clear
override public func drawText(in rect: CGRect) {
let shadowOffset = self.shadowOffset
let textColor = self.textColor
let c = UIGraphicsGetCurrentContext()
c?.setLineWidth(outlineWidth)
c?.setLineJoin(.round)
c?.setTextDrawingMode(.stroke)
textAlignment = .center
self.textColor = outlineColor
super.drawText(in: rect)
c?.setTextDrawingMode(.fill)
self.textColor = textColor
self.shadowOffset = CGSize(width: 0, height: 0)
super.drawText(in: rect)
self.shadowOffset = shadowOffset
}
}
}
}
`
PINCH
`
#objc func pinchRecoginze(_ pinchGesture: UIPinchGestureRecognizer) {
guard pinchGesture.view != nil else { return }
let view = pinchGesture.view!
if pinchGesture.view is UILabel {
let textLabel = view as! UILabel
if pinchGesture.state == .began {
let font = textLabel.font
pointSize = font!.pointSize
pinchGesture.scale = textLabel.font!.pointSize * 0.1
}
if 1 <= pinchGesture.scale && pinchGesture.scale <= 10 {
textLabel.font = UIFont(name: textLabel.font!.fontName, size: pinchGesture.scale * 10)
print("label_tag_PINCH: \(textLabel.tag) ")
resizeLabelToText(textLabel: textLabel, tag: textLabel.tag)
}
}
}
`
func resizeLabelToText(textLabel: UILabel, tag: Int) {
let labelSize = textLabel.intrinsicContentSize
textLabel.bounds.size = labelSize
label.addTextOutline(usingColor: .red, outlineWidth: 10, tagX: tag)
}
label.addTextOutline(usingColor: .red, outlineWidth: 10, tagX: label.tag)
enter image description here

i want to set the custom stacking button class's button text differently for each ViewController

I set the custom stackButtonView Like this.
I want to use this class to the another class with changing buttonText context.
["1","2","3","4"] >> ["a","b","c","d"]
I thought buttonText set to global property . Am I right? ..
class kindsButtonView: UIView{
//...
let buttonText: [String] = [
"1","2","3","4"
]
public func addButtonsToStackView() {
let numberOfButtons = buttonText.count
let column = 2
let row: Int
if numberOfButtons % column != 0 {
row = (numberOfButtons / column) + 1
} else {
row = numberOfButtons / column
}
for i in 0 ..< row {
let horizontalSv = UIStackView()
horizontalSv.axis = .horizontal
//horizontalSv.alignment = .fill
horizontalSv.distribution = .fillEqually
horizontalSv.spacing = 8
for j in 0 ..< column {
if buttonText.count == i*column + j {
let hideButton = SurveyButton()
// make tranparant !
hideButton.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0).cgColor
hideButton.layer.shadowOffset = CGSize(width: 0, height: 0)
hideButton.layer.shadowOpacity = 0
hideButton.layer.shadowRadius = 0
hideButton.layer.masksToBounds = false
hideButton.layer.shadowOffset = CGSize(width: 0, height: 0)
horizontalSv.addArrangedSubview(hideButton)
break
}
let button = SurveyButton()
button.setTitle("\(buttonText[ i*column + j ])",for: .normal)
button.titleLabel?.font = UIFont(name: "AvenirNext-DemiBoldItalic", size: 15)
button.tag = i*column + j + 1
button.addTarget(self, action: #selector(handleCleaningKinds(_:)), for: .touchUpInside)
horizontalSv.addArrangedSubview(button)
}
stackView1.addArrangedSubview(horizontalSv)
}
stackView.addArrangedSubview(stackView1)
}
Yes, your approach will mostly work.
If you want me to suggest a few changes, then:
Place addButtonsToStackView() inside an appropriate extension class (in your case UIView).
Use buttonText as a private property inside the class where you will use it.
Pass the buttonText properly into addButtonsToStackView() preferably as a parameter.

Layout programmatically created UILabels in a UIView

I have this:
Created via this piece of code:
// Add hashtag collection to a post
func addHashtags(container: UIView, constraint: NSLayoutConstraint) -> Void {
let screenSize: CGRect = UIScreen.main.bounds
let screenWidth = screenSize.width - 16 - 16
var currentOriginX: CGFloat = 0
var currentOriginY: CGFloat = 0
for j in 0..<self.pseudo.count {
if currentOriginY < 144 {
// Create a new label
let labelHashtag = RoundedLabel()
labelHashtag.rounded = true
tagLabels.append(labelHashtag)
print(tagLabels.count)
// Set its properties (title, colors, corners, etc)
labelHashtag.text = pseudo[j] as? String
labelHashtag.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
labelHashtag.textAlignment = .center
labelHashtag.textColor = UIColor.black
labelHashtag.backgroundColor = UIColor.white
labelHashtag.layer.borderColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.0).cgColor
labelHashtag.layer.borderWidth = 1
// Set its frame width and height
labelHashtag.frame.size.width = labelHashtag.intrinsicContentSize.width + tagPadding
labelHashtag.frame.size.height = tagHeight
// Add it to the scroll view
container.addSubview(labelHashtag)
// If current X + label width will be greater than container view width
// .. move to next row
if (currentOriginX + labelHashtag.frame.width > screenWidth) {
tagLabels[0].textColor = .red
print("übrig")
print(screenWidth - currentOriginX)
currentOriginX = 0
currentOriginY += tagHeight + tagSpacingY
}
// Set the btn frame origin
labelHashtag.frame.origin.x = currentOriginX
labelHashtag.frame.origin.y = currentOriginY
// Increment current X by btn width + spacing
currentOriginX += labelHashtag.frame.width + tagSpacingX
} else if currentOriginY == 90 {
}
// Update container view height
constraint.constant = currentOriginY + tagHeight
}
container.layoutIfNeeded()
}
I want to center all items in each row. I imagine I have to calculate the remaining width of my UIView and add a margin to the first item.
How can I add a margin to my UILabel? I can access it via tagLabels[0] and I think I know how to calculate the remaining width, but I don't know how I can add the margin to it.

How can I increase the y of a label, in swift?

So I am very new in Swift and I can't figure out how to increase the y value from a label.
I am trying to show in a label, some messages that a user types in an input... like a chat view.
So I have this code, but it puts all the messages one above the other:
I know that it is very messy, I am sorry for that.
Thanks!
//my label
#IBOutlet weak var label: UILabel!
//my text field
#IBOutlet weak var textF: UITextField!
#IBAction func buttonPressed(sender: AnyObject) {
//create a variable(input) to store my text from the TextField
var input = textF.text
//put that text in the label
label.text = input
var label2 : UILabel = UILabel(frame: CGRectMake(20, 20, 200, 21))
var isSendMessage: Bool = true {
didSet {
if isSendMessage {
var input = textF.text
label.text = input
textF.text = " "
// self.view.label.origin.y += 10
} else {
var input = textF.text
label2.text = input
textF.text = " "
}
}
}
label2.center = CGPointMake(160, 284)
label2.textAlignment = NSTextAlignment.Center
self.view.addSubview(label2)
//empty text field
textF.text = " "
label2.center = CGPointMake(160, 284)
label2.textAlignment = NSTextAlignment.Center
label2.text = input
//add it to the view
self.view.addSubview(label2)
}
Try this
Don't update Y axis directly as if your Y value is greater than the screen height then label will go off the screen.
Try the following code.
// Taking height and width of the screen
var height = UIScreen.mainScreen().bounds.size.height;
var width = UIScreen.mainScreen().bounds.size.width;
var x = 164.0 // Fixed height of the label
if x < height
{
x += 20.0 // Incrementing height value
if (height - 20) >= x // Checking the difference between screen height and x, so it doesn't go beyond the screen.
{
label.frame = CGRectMake(20.0, x, 200.0, 21.0)
self.view.addSubview(label)
}
else
{
// Setting default height
label.frame = CGRectMake(20.0,164.0, 200.0, 21.0)
self.view.addSubview(label)
}
}
Hope this will be helpful.
In a quick answer to your question, if you are just looking to change the position on the y-axis you can use the property .y under .center
self.yourLabel.center.y = self.yourLabel.center.y + 10

Is it possible to customize UITabBarItem Badge?

The question below is similar as mine.
How to use a custom UIImage as an UITabBarItem Badge?
Is it possible to use a background image instead of drawing it myself?
I think it's fine since my app will only use a 1-digit badgeValue.
If it is not really possible, I want to know if we can change the badge color instead.
The answers in the question below are not really helping.
Is it possible to change UITabBarItem badge color
This is your best bet. Add this extension at the file scope and you can customise the badges however you like. Just call self.tabBarController!.setBadges([1,0,2]) in any of your root view controllers.
To be clear that is for a tab bar with three items, with the badge values going from left to right.
If you want to add images instead just change the addBadge method
extension UITabBarController {
func setBadges(badgeValues: [Int]) {
var labelExistsForIndex = [Bool]()
for _ in badgeValues {
labelExistsForIndex.append(false)
}
for view in self.tabBar.subviews where view is PGTabBadge {
let badgeView = view as! PGTabBadge
let index = badgeView.tag
if badgeValues[index] == 0 {
badgeView.removeFromSuperview()
}
labelExistsForIndex[index] = true
badgeView.text = String(badgeValues[index])
}
for i in 0...(labelExistsForIndex.count - 1) where !labelExistsForIndex[i] && (badgeValues[i] > 0) {
addBadge(index: i, value: badgeValues[i], color: .red, font: UIFont(name: "Helvetica-Light", size: 11)!)
}
}
func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
let itemPosition = CGFloat(index + 1)
let itemWidth: CGFloat = tabBar.frame.width / CGFloat(tabBar.items!.count)
let bgColor = color
let xOffset: CGFloat = 5
let yOffset: CGFloat = -12
let badgeView = PGTabBadge()
badgeView.frame.size = CGSize(width: 12, height: 12)
badgeView.center = CGPoint(x: (itemWidth * itemPosition) - (itemWidth / 2) + xOffset, y: 20 + yOffset)
badgeView.layer.cornerRadius = badgeView.bounds.width/2
badgeView.clipsToBounds = true
badgeView.textColor = UIColor.white
badgeView.textAlignment = .center
badgeView.font = font
badgeView.text = String(value)
badgeView.backgroundColor = bgColor
badgeView.tag = index
tabBar.addSubview(badgeView)
}
}
class PGTabBadge: UILabel { }
Here is another solution based on TimWhiting's answer:
extension UITabBar {
func setBadge(value: String?, at index: Int, withConfiguration configuration: TabBarBadgeConfiguration = TabBarBadgeConfiguration()) {
let existingBadge = subviews.first { ($0 as? TabBarBadge)?.hasIdentifier(for: index) == true }
existingBadge?.removeFromSuperview()
guard let tabBarItems = items,
let value = value else { return }
let itemPosition = CGFloat(index + 1)
let itemWidth = frame.width / CGFloat(tabBarItems.count)
let itemHeight = frame.height
let badge = TabBarBadge(for: index)
badge.frame.size = configuration.size
badge.center = CGPoint(x: (itemWidth * itemPosition) - (0.5 * itemWidth) + configuration.centerOffset.x,
y: (0.5 * itemHeight) + configuration.centerOffset.y)
badge.layer.cornerRadius = 0.5 * configuration.size.height
badge.clipsToBounds = true
badge.textAlignment = .center
badge.backgroundColor = configuration.backgroundColor
badge.font = configuration.font
badge.textColor = configuration.textColor
badge.text = value
addSubview(badge)
}
}
class TabBarBadge: UILabel {
var identifier: String = String(describing: TabBarBadge.self)
private func identifier(for index: Int) -> String {
return "\(String(describing: TabBarBadge.self))-\(index)"
}
convenience init(for index: Int) {
self.init()
identifier = identifier(for: index)
}
func hasIdentifier(for index: Int) -> Bool {
let has = identifier == identifier(for: index)
return has
}
}
class TabBarBadgeConfiguration {
var backgroundColor: UIColor = .red
var centerOffset: CGPoint = .init(x: 12, y: -9)
var size: CGSize = .init(width: 17, height: 17)
var textColor: UIColor = .white
var font: UIFont! = .systemFont(ofSize: 11) {
didSet { font = font ?? .systemFont(ofSize: 11) }
}
static func construct(_ block: (TabBarBadgeConfiguration) -> Void) -> TabBarBadgeConfiguration {
let new = TabBarBadgeConfiguration()
block(new)
return new
}
}
You can use a more robust solution #UITabbarItem-CustomBadge.
Demo
Simple two line of code can get you going
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//supplying the animation parameter
[UITabBarItem setDefaultAnimationProvider:[[DefaultTabbarBadgeAnimation alloc] init]];
[UITabBarItem setDefaultConfigurationProvider:[[DefaultSystemLikeBadgeConfiguration alloc] init]];
//rest of your code goes following...
return YES;
}
well... changing the background of the built-in badge does not seem possible to me. But what IS possible instead, is the following:
Subclass the TabBarController, build a custom view laid out in a NIB, add it to the view hierarchy at the location in the tab bar, where you want it to be.
In the custom view you can set up an image as background and a label on top of that background, that will display the number value you can then change by code.
Then you need to figure out the horizontal and vertical location of your custom view where you want to place your view inside of the tab bar.
Hope this helps a little bit.
Sebastian
TimWhiting's answer updated to Swift 4 with the removal of some force unwrapping.
extension UITabBarController {
func setBadges(badgeValues: [Int]) {
var labelExistsForIndex = [Bool]()
for _ in badgeValues {
labelExistsForIndex.append(false)
}
for view in tabBar.subviews {
if let badgeView = view as? PGTabBadge {
let index = badgeView.tag
if badgeValues[index] == 0 {
badgeView.removeFromSuperview()
}
labelExistsForIndex[index] = true
badgeView.text = String(badgeValues[index])
}
}
for i in 0 ... labelExistsForIndex.count - 1 where !labelExistsForIndex[i] && badgeValues[i] > 0 {
addBadge(
index: i,
value: badgeValues[i],
color: UIColor(red: 4 / 255, green: 110 / 255, blue: 188 / 255, alpha: 1),
font: UIFont(name: "Helvetica-Light", size: 11)!
)
}
}
func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
guard let tabBarItems = tabBar.items else { return }
let itemPosition = CGFloat(index + 1)
let itemWidth: CGFloat = tabBar.frame.width / CGFloat(tabBarItems.count)
let bgColor = color
let xOffset: CGFloat = 12
let yOffset: CGFloat = -9
let badgeView = PGTabBadge()
badgeView.frame.size = CGSize(width: 17, height: 17)
badgeView.center = CGPoint(x: (itemWidth * itemPosition) - (itemWidth / 2) + xOffset, y: 20 + yOffset)
badgeView.layer.cornerRadius = badgeView.bounds.width / 2
badgeView.clipsToBounds = true
badgeView.textColor = UIColor.white
badgeView.textAlignment = .center
badgeView.font = font
badgeView.text = String(value)
badgeView.backgroundColor = bgColor
badgeView.tag = index
tabBar.addSubview(badgeView)
}
}
class PGTabBadge: UILabel {}
Sample Image