How to show pyramid pattern on UILabel on Button Click(swift language) - ios

///swift iOS
/// I have tried with below code
#IBOutlet weak var myLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
func magic(choose: String, row: Int) -> String {
var name = ""
for i in 1...row {
name += (String.init(repeating: " ", count: row-i)+String.init(repeating: choose, count: 2*i-1))
}
return name
}
#IBAction func btnPressed(_ sender: UIButton) {
let result = magic(choose: "0", row: 5)
myLbl.text = result
}
plz check images which type of response I am getting
}[I am getting output at this manner][1]
[1]: https://i.stack.imgur.com/YdV8f.png
we have to show this type of response on my UILabel

Please open up a fresh playground and paste the following code in:
import UIKit
let label = UILabel()
label.text = " 0 \n000" // simple demo text
label.numberOfLines = 0 // unlimited number of lines
label.font = .monospacedSystemFont(ofSize: 14, weight: .regular) // monospaced font so that columns are aligned
label.sizeToFit() // tell the label to evaluate its content and adjust its size to fit
It should display a basic example of what you want and give you all the information you need to update your code accordingly.

Related

how to create tappable text in uitextview in swift

I want to create tappable text when I tap on those text then fire some action like call any function do some operation of that text I catnap on any text not on whole uitextview
Try this -
override func viewDidLoad() {
super.viewDidLoad()
// You must set the formatting of the link manually
let linkAttributes: [NSAttributedStringKey: Any] = [
.link: NSURL(string: "https://www.apple.com")!,
.foregroundColor: UIColor.blue
]
let attributedString = NSMutableAttributedString(string: "Just click here to register")
// Set the 'click here' substring to be the link
attributedString.setAttributes(linkAttributes, range: NSMakeRange(5, 10))
self.textView.delegate = self
self.textView.attributedText = attributedString
self.textView.isUserInteractionEnabled = true
self.textView.isEditable = false
}
If I understand your question correctly, you want to click on a text view and call a function. You can use UITapGestureRecognizer.
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(labelTapped))
textView.addGestureRecognizer(tapGestureRecognizer)
}
#objc func labelTapped(){
print("Do something")
}
I've faced with problem same like your and I've tried many things to resolve. The best approach will be use Atributika (or similar) library. You will not regret this decision. It's easy to use and have a lot features.
https://github.com/psharanda/Atributika
If I understand your question properly then you could just add a button then change the button text to the text you want. Then like normal text you can mess with the colour, border or fill. After you have added this to your app link it up as an action with your view controller.swift file
Here is an example from my app 'Health Dash':
Image 1
Image 2
Then the swift 4 code:
import UIKit
class FriendsViewController: UIViewController {
#IBAction func exampleText(_ sender: Any) {
print("When you click this button something happens")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Here is an image of what it should look like:
Image 3

Swift 4 iOS - Word Count from UITextField

Trying to make a "word count" feature using Swift 4 iOS - UITextField. The following code is unable to print the .count for strings typed inside my UITextField.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//INPUT BOX - for Word Count!
let INPUT : UITextField = UITextField(frame: CGRect(x: 35, y: 200, width: 350, height:50))
INPUT.placeholder = "Type Words separated with Spaces!"
INPUT.font = UIFont.init(name:"times", size: 22)
INPUT.backgroundColor = UIColor(red:0x00 ,green:0xff, blue:0x00 ,alpha:1)
self.view.addSubview(INPUT)
//variable holding the value of text typed
let strings : String! = INPUT.text
//variable holding the methods for detecting spaces and new lines
let spaces = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters)
//variable storing the amount of words minus the spaces
let words = strings.components(separatedBy: spaces)
//method to display the word count in the console
print(words.count)
}
}
This error is being printed in the console:
"Result" => : 0
That's because your textview has no text in it at that point.
Try this:
INPUT.text = "Some Text"
Do get the text from an actual input:
INPUT.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
func textFieldDidChange(_ textField: UITextField) {
let strings : String! = INPUT.text
let spaces = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters)
let words = strings.components(separatedBy: spaces)
print(words.count)
}

Adding a random number in front of a UI Label

I want to add a random number in front of my UI label this is my code which is not working.
#IBOutlet var Label2: UILabel!
#IBOutlet var Label1: UILabel!
Label1.text! = "1"
Label2.text! = "2"
var random = arc4random_uniform(2) + 1
if Label(random).text! == "1" {
print("This is Label 1")
} else {
print ("This is Label 2")
}
If there is any other way to add a random number in front of UI Label i'll welcome the answer.
Use IBOutletCollection
#IBOutlet var label: [UILabel]!
label[0].text! = "1"
label[1].text! = "2"
var random:Int = Int(arc4random_uniform(2))
if label[random].text! == "1" {
print("This is Label 1")
} else {
print ("This is Label 2")
}
UPDATE:
make sure all the labels you want in the array is highlighted
right click and drag to your collection view
set connection to Outlet Collection
You can put your labels into an array and then pick a random one:
#IBOutlet var label1: UILabel!
#IBOutlet var label2: UILabel!
var labels = [UILabel]()
override func viewDidLoad() {
super.viewDidLoad()
labels.append(label1)
labels.append(label2)
var random = Int(arc4random_uniform(2))
if labels[random].text! == "1" {
print("This is Label 1")
} else {
print ("This is Label 2")
}
}
It seems that what you're trying to achieve with Label(random) is to dynamically change the Label variable name. As pointed in other question, this is probably a bad practice. So, I would recommend you read Create a variable in swift with dynamic name, first.
[edit:]
Just to give an example, you can do that using an Array, such as:
// Creating two UILabels:
var label1 = UILabel()
var label2 = UILabel()
label1.text = "0"
label2.text = "1"
// An array of Labels, which starts from 0:
let labels: [UILabel] = [label1, label2]
// Another random function which goes to the size of the array:
var i = random() % labels.count
// Just to check the random number:
print("Your random number: \(i)")
// And then, the test:
if labels[i].text == "0" {
print("This is Label 0: \(labels[i].text)")
} else {
print ("This is Label 1: \(labels[i].text)")
}
Just apply these ideas to your IBOutlet variables.
Hope it helps :D

Last line in label for cell wont appear with auto layout and dynamic cell height

I am having some serious trouble getting my multiline label to show all of its lines. Often, the last line of the label simply does not appear, but it is apparent that the dynamically calculated cell height has taken in to account that it should have appeared, leaving around the appropriate amount of white space left over in my cell.
The affected label can display 1-7 lines depending on the data. I have played around with many various constraints to try and get it to display but regardless of what is on the last line, it just won't display.
The weird thing is, sometimes it will display when I segue in to the VC, but then when I use the segmented controller inside the VC to display different data and then go back again, the last line will again not display. The opposite happens frequently too (last line of label cutting off when I segue in to the VC, but then using the segmented controller inside the VC to change the displayed data and then go back, it will then display fine).
Things I have ensured: The label is set to word wrap, has line count of 0, has a height greater than or equal to the height of one of it's lines, its resistance and vertical content hugging is set to the highest of anything in the cell, and the width is set appropriately.
The below code is how I determine how many lines the label will have:
let descString = NSMutableAttributedString()
let bountyStart = NSMutableAttributedString(string: "Bounty: ", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)])
let bountyDesc = NSMutableAttributedString(string: bounty.description)
descString.appendAttributedString(bountyStart)
descString.appendAttributedString(bountyDesc)
let bLine = NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName : UIFont.systemFontOfSize(2)])
descString.appendAttributedString(bLine)
if !(bounty.turtles == 0.0){
let turtleStart = NSMutableAttributedString(string: "Your turtle count: ")
let turtleAmount = NSMutableAttributedString(string: bounty.turtleCount.description)
descString.appendAttributedString(turtleStart)
descString.appendAttributedString(turtleAmount)
}
descriptionLabel.attributedText = descString
In the screen shot below, you can see that the height of the cell is being calculated appropriately but for some reason, the last line of the label just refuses to show. It should appear after the "is for noobs" line. I've manipulated the white space to appear after the line instead of elsewhere by setting the problem labels bottom to constraint to be greater than or equal, and all other top to bottom constraints as equal to.
Constraints of the problem label:
I've been stumped for quite a while on this one, and I'm starting to think it's not the constraints I've set but something much deeper. All though I would love to be proven wrong.
Here is my VC code.
import UIKit
class TrendingVC: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var menubtn:UIBarButtonItem!
#IBOutlet var trendingTableView:UITableView!
var trendingToggle:Int = 0
let nwt = NWTrending()
let appUserId = NSUserDefaults.standardUserDefaults().stringForKey("UserId") ?? "1" //#TODO: remove ?? 1
var bountyArr: [Bounty] = []
var compArr: [Completion] = []
var peopleArr: [Person] = []
var userId: String = "0"
var username: String = ""
let bountyCellIdentifier = "BountyCellNew"
let personCellIdentifier = "PersonCell"
let completedCellIdentifier = "TrendingCompletedImageCell"
#IBAction func toggleTrending(sender:UISegmentedControl){
switch sender.selectedSegmentIndex{
case 0:
//loads the bounties on segmented control tab
trendingToggle=0
nwt.getTrendingBounties(appUserId, position: 0){(bountyArr, err) in //#TODO: change pos
self.bountyArr = bountyArr as [Bounty]
self.reloadTableViewContent()
}
case 1:
trendingToggle=1
nwt.getTrendingCompletions(appUserId, position: 0){(compArr, err) in
self.compArr = compArr as [Completion]
self.reloadTableViewContent()
}
case 2:
trendingToggle=2
nwt.getTrendingPeople(appUserId, position: 0){(peopleArr, err) in
self.peopleArr = peopleArr as [Person]
self.reloadTableViewContent()
}
default:
break
}
//reloadTableViewContent()
}
override func viewDidLoad() {
super.viewDidLoad()
trendingTableView.estimatedRowHeight = 300.0
trendingTableView.rowHeight = UITableViewAutomaticDimension
/******* Kyle Inserted *******/
//for followers and following back button text, you set it here for when you segue into that section
let backItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backItem
/******* END Kyle Inserted *******/
trendingTableView.allowsSelection = false;
trendingTableView.delegate = self
trendingTableView.dataSource = self
//sidebar code
if self.revealViewController() != nil {
menubtn.target = self.revealViewController()
menubtn.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
//loads the bounty on segue
nwt.getTrendingBounties(appUserId, position: 0){(bountyArr, err) in
self.bountyArr = bountyArr as [Bounty]
self.reloadTableViewContent()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//deselectAllRows()
}
func deselectAllRows() {
if let selectedRows = trendingTableView.indexPathsForSelectedRows() as? [NSIndexPath] {
for indexPath in selectedRows {
trendingTableView.deselectRowAtIndexPath(indexPath, animated: false)
}
}
}
func reloadTableViewContent() {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.trendingTableView.reloadData()
println("reloading table view content")
self.trendingTableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false)
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(trendingTableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if trendingToggle == 0{
return bountyArr.count
}
else if trendingToggle == 1{
return compArr.count
}
else {
return peopleArr.count
}
}
func tableView(trendingTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if trendingToggle == 0{
return bountyCellAtIndexPath(indexPath)
}
else if trendingToggle == 1{
return completedCellAtIndexPath(indexPath)
}
else{
return personCellAtIndexPath(indexPath)
}
}
//calls method to set and display each trending bounty cell
func bountyCellAtIndexPath(indexPath:NSIndexPath) -> BountyCellNew {
let cell = trendingTableView.dequeueReusableCellWithIdentifier(bountyCellIdentifier) as! BountyCellNew
var bounty = bountyArr[indexPath.row]
cell.setBountyCellTrending(bounty)
return cell
}
func completedCellAtIndexPath(indexPath:NSIndexPath) -> CompletedCell{
let cell = trendingTableView.dequeueReusableCellWithIdentifier(completedCellIdentifier) as! CompletedCell
var comp = compArr[indexPath.row]
cell.setTrendingCompletedCell(comp)
return cell
}
func personCellAtIndexPath(indexPath:NSIndexPath) -> PersonCell{
let cell = trendingTableView.dequeueReusableCellWithIdentifier(personCellIdentifier) as! PersonCell
var peop = peopleArr[indexPath.row]
cell.setTrendingPeopleCell(peop)
return cell
}
}
Unable to comment due to rep low.
This seems like a IB thing, very likely constraints.
Make sure that any component's top constraint placed under this multiline UILabel is set to the bottom of said UILabel.
For example, in this project of mine, both the TitleView and TimeAndDetailsView contain UILabels that span multiplelines. In order to allow autolayout to properly space things all constraints need to be in order, also notice how the top constraint of TimeAndDetails is the bottom of TitleView
Edit note:
Before you tableView.reloadData() type the following 2 lines, or if uncertain, put it inside viewDidLoad
tableView.estimatedRowHeight = 60 //Type your cell estimated height
tableView.rowHeight = UITableViewAutomaticDimensionhere
Went to sleep last night, ok so I decided to add your code to my details label from the storyboards picture I had posted before, and it seems to have displayed just fine. I have a few questions and pointers below.
let descString = NSMutableAttributedString()
let bountyStart = NSMutableAttributedString(string: "Bounty: ", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)])
let bountyDesc = NSMutableAttributedString(string: "this would be 'bounty.description and is set to size 40", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(40)])
descString.appendAttributedString(bountyStart)
descString.appendAttributedString(bountyDesc)
let bLine = NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName : UIFont.systemFontOfSize(10)])
descString.appendAttributedString(bLine)
let turtleStart = NSMutableAttributedString(string: "Your turtle count: ")
let turtleAmount = NSMutableAttributedString(string: "random number 1234 goes here")
descString.appendAttributedString(turtleStart)
descString.appendAttributedString(turtleAmount)
detailsLabel.attributedText = descString
Sadly, this is in a scrollview and not in a cell, so there is the first difference. My first question; is your descriptionLabel.attributedText supposed to display different fontscolors or fonttypes/sizes?, if not then I would say to just use descriptionLabel.text instead of descriptionLabel.attributedText.
Now the fact that there is white space but nothing showing us makes me wonder if bounty.turtleCount.description was previously set to color white somewhere else, or you are simply seeing the newlines you added \n\n and nothing is there because if !(bounty.turtles == 0.0) doesnt execute. Are you sure the that if statement is executed? place a breakpoint and follow along to make sure the values are appended to descString
If this is all correct, then my guess would still be on constraints.
Could you elaborate on, quote from you; "sometimes it will display when I segue in to the VC, but then when I use the segmented controller inside the VC to display different data and then go back again, the last line will again not display." what are you doing different in the seg control when loading the values and reloading the tableview that makes it not display, and under what conditions does it work properly when you segue.
I updated xcode and now this doesn't happen anymore.

How can I create a "hyperlink" with Swift?

I'm trying to make separate pieces of text UILabels clickable. What I'm looking for is commonly known as a hyperlink in web development.
Link 1
Link 2
Link 3
Each a tag is its own UILabel, and it would ideally open Safari to the specified href when the text between the tags is clicked.
I've found a bevy of resources on how to do this sort of thing in Objective-C, but they all seem unnecessarily complicated and don't translate well to Swift (they fit an Objective-C organizational structure that doesn't work well in Swift and goes against the recommended way of using the language).
Here are a few:
How to add hyperlink in iPhone app?
How to make a clickable link inside a NSTextField and Cocoa
Text as Hyperlink in Objective-C
If I had a 3 UILabels,
Item 1
Item 2
Item 3
then what would be the best "Swift-y" way to make each item open to a different URL in Safari?
I could create separate buttons for each, but the UILabels are programmatically populated, so I was thinking that making the text respond to taps might be a better option.
Swift 3
I created a LinkUILabel class in github:
https://github.com/jorgecsan/LinkUILabel
With this you only need add the url inspectable as the shows the image:
or assign the url variable programmatically:
linkUILabel.url = "www.example.com"
If you want to implement by your self also I found that solution!:)
using:
// This is the label
#IBOutlet weak var label: UILabel!
override func loadView() {
super.loadView()
// This is the key
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onClicLabel(sender:)))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)
}
// And that's the function :)
func onClicLabel(sender:UITapGestureRecognizer) {
openUrl("http://www.google.com")
}
func openUrl(urlString:String!) {
let url = URL(string: urlString)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
Hope it helps!:)
The One approach would be something like the following.
The assumptions are:
self.urls is a string array containing the urls associated with each UILabel.
Each UILabel tag has been set to the corresponding index in the array
labelTapped: is set as the touchUpInside handler for the labels.
import Foundation
import UIKit
class urltest {
var urls:[String]
init() {
self.urls=[String]() // Load URLs into here
}
#IBAction func labelTapped(sender:UILabel!) {
let urlIndex=sender.tag;
if (urlIndex >= 0 && urlIndex < self.urls.count) {
self.openUrl(self.urls[urlIndex]);
}
}
func openUrl(url:String!) {
let targetURL=NSURL.URLWithString(url)
let application=UIApplication.sharedApplication()
application.openURL(targetURL);
}
}
Hyperlink via UITextView
var termsConditionsTextView: UITextView = {
let view = UITextView()
view.backgroundColor = .clear
view.textAlignment = .left
let firstTitleString = "By registering for THIS_APP I agree with the "
let secondTitleString = "Terms & Conditions"
let finishTitleString = firstTitleString + secondTitleString
let attributedString = NSMutableAttributedString(string: finishTitleString)
attributedString.addAttribute(.link, value: "https://stackoverflow.com", range: NSRange(location: firstTitleString.count, length: secondTitleString.count))
view.attributedText = attributedString
view.textContainerInset = .zero
view.linkTextAttributes = [
.foregroundColor: UIColor.blue,
.underlineStyle: NSUnderlineStyle.single.isEmpty
]
view.font = view.font = UIFont(name: "YOUR_FONT_NAME", size: 16)
view.textColor = UIColor.black
return view }()

Resources