I have a text label (NSTextField). I want it to pin to the upper left vertex of every object to show an element's number in UI.
But my label shows only ZERO and doesn't move (it stays in the upper left corner). What I did wrong?
Here is my code in AppDelegate.swift:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var drawingView: DrawingView!
#IBOutlet weak var label: NSTextField!
var localArray: [CGPoint] = []
func applicationDidFinishLaunching(aNotification: NSNotification) {
label.textColor = NSColor(calibratedRed: 0.15, green: 0, blue: 0.75, alpha: 0.3)
label.font! = NSFont(name: "Arial Bold", size: 60)!
label.backgroundColor = NSColor.clearColor()
label.stringValue = "\(localArray.count/4)"
for (pointIndex, _) in localArray.enumerate() {
let point = CGPoint(x: (localArray[(pointIndex/4)+1].x), y: (localArray[(pointIndex/4)+1].y))
label.sizeToFit()
label.frame = CGRect(origin: point, size: CGSize(width: label.bounds.width, height: label.bounds.height))
}
}
And here is my code in DrawingView.swift:
var delegate = NSApplication.sharedApplication().delegate as! AppDelegate
delegate.localArray = myArray.map { return $0.coordSequence()[0] }
myArray contains cgpoints.
Am I right putting label parameters inside applicationDidFinishLaunching method?
You are trying to update NSTextField probably from wrong thread.
dispatch_async(dispatch_get_main_queue(),{
label.stringValue = "\((localArray.count/4)+1)"
})
Try to investigate you're array i could make assumption that when you set value of the label localArray.count is 0. Also keep in mind that you are working with Int and if localArray.count is 3 so 3/4 will be 0.
Related
I made a simple timer app and I want to add a background picture or video in the background. However, I cannot do it and I do not know why.
Can someone tell me why the picture does not show up in the background? I set the background in the viewDidLoad method. Maybe the #IBOutlet var backgroundView: UIView! part is wrong? I connected it with the given UIView when I made this Xcode project.
class ViewController: UIViewController, UITableViewDelegate {
let mainStopwatch = Stopwatch()
let lapStopwatch = Stopwatch()
var isPlay: Bool = false
var laps: [String] = []
//UI components
#IBOutlet weak var lapRestButton: UIButton!
#IBOutlet weak var playPauseButton: UIButton!
#IBOutlet weak var lapTimerLabel: UILabel!
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var lapsTableView: UITableView!
#IBOutlet var backgroundView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.view.addBackground(name: "nathan-dumlao-iXXyrEwZgiU-unsplash")
lapRestButton.isEnabled = false
lapsTableView.dataSource = self
lapsTableView.delegate = self
}
//UI Settings
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
//Actions
#IBAction func playPauseTimer(_ sender: Any) {
lapRestButton.isEnabled = true
changeButton(lapRestButton, title: "Lap", color: .black)
}
}
And this is another swift file for setting the background picture.
extension UIView {
func addBackground(name: String) {
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
imageViewBackground.image = UIImage(named: name)
imageViewBackground.contentMode = .scaleAspectFill
self.addSubview(imageViewBackground)
self.sendSubviewToBack(imageViewBackground)
}
var timer = Timer()
var counter = 0 // the counter is use for the index of array in below code
var imageArr = ["image","image1","image2"] //Image arr
override func viewDidLoad() {
super.viewDidLoad()
self.addBackground(name: "image") // set default image on your view
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true) // timer will start and it will change view background image after one min you can change time according to your requirement.
}
// called every time interval from the timer
#objc func timerAction() {
self.addBackground(name: self.imageArr[counter]) // here we are change our view background image when timer function is run on every min
counter += 1 // every-time counter will increment by one so the image array index will also increment and we will get our new image
}
// that's your code only you need to change one line that last one
func addBackground(name: String) {
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
imageViewBackground.image = UIImage(named: name)
imageViewBackground.contentMode = .scaleAspectFit
self.viewref.addSubview(imageViewBackground) // here we will set the image view to our view
}
hope this will help you for change your background of view.
Thanks.
Seems like you've don't using your backgroundView to anywhere in class code , So first
Remove backgroundView from storyBoard and also remove code from class file
viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
self.addBackground(name: "nathan-dumlao-iXXyrEwZgiU-unsplash") //Update this line
lapRestButton.isEnabled = false
lapsTableView.dataSource = self
lapsTableView.delegate = self
}
Update your extension code to below one
extension YourViewController {
func addBackground(name: String) {
let width = self.view.frame.size.width
let height = self.view.frame.size.height
let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
imageViewBackground.image = UIImage(named: name)
imageViewBackground.contentMode = .scaleAspectFill
self.view.addSubview(imageViewBackground)
// self.sendSubviewToBack(imageViewBackground) //Comment this line
}
}
I'm a little new in swift. I'm trying to make a simple scrollview with a label that changes its value, but I can not get it to work properly.
This is my code:
class ConsejosController: UIViewController, UIScrollViewDelegate {
var asunto = ["value1", "value2"]
#IBOutlet weak var lbl_asunto: UILabel!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
var contentWidth: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
for etiqueta in 0...1{
contentWidth += view.frame.width
lbl_asunto.text = asunto[etiqueta]
}
scrollView.contentSize = CGSize(width: contentWidth, height: view.frame.height)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x / CGFloat(375) )
}
}
This don't work properly. Directly show "value2" and don't scroll
Any advice?
I made the for cycle in this way:
for etiqueta in 0...1{
contentWidth += view.frame.width
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
label.center = CGPoint(x: 160, y: 285)
label.textAlignment = .center
label.text = asunto[etiqueta]
self.scrollView.addSubview(label)
}
Now scrolling well, but show two labels 'value1' and 'value2' in the same page one over another, and the second page empty.
I had a corner radius problem with all of my UIButtons, but was finally able to resolve the issue by following the solution at (Setting corner radius through viewDidAppear() or viewWillLayoutSubviews()?
) However, now I have "lost" all of my attributed button titles. I have been battling this issue for a couple of weeks and feel like I am very close to figuring it all out. I apologize if this is a poorly phrased question as I am still relatively new to Swift.
Here is the application I am working on:
my default iOS calculator project
In my Swift-file, UIButtonExtension.swift, I have the following:
import Foundation
import UIKit
extension UIButton {
override open func layoutSubviews() {
super.layoutSubviews()
let radius = min(bounds.width, bounds.height) / 2
layer.cornerRadius = radius
}
}
In one of my other Swift-files, myCalculatorViewController.swift, I have:
import UIKit
class myCalculatorViewController: UIViewController {
#IBOutlet weak var tag1_Button: UIButton!
#IBOutlet weak var tag2_Button: UIButton!
#IBOutlet weak var tag3_Button: UIButton!
// .....
#IBOutlet weak var tag19_Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// main/basic calc button view controller
tag1_Button.titleLabel?.textAlignment = .center
tag1_Button.contentHorizontalAlignment = .center
tag1_Button.titleLabel?.numberOfLines = 1
let str_tag1_Button = NSMutableAttributedString(string: "AC")
str_tag1_Button.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize: 10), range: NSMakeRange(0, 2))
str_tag1_Button.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0), range: NSMakeRange(0, 2))
tag1_Button.setAttributedTitle(str_tag1_Button, for: .normal)
tag1_Button.backgroundColor = UIColor(red: 40/255.0, green: 247/255.0, blue: 45/255.0, alpha: 1.0)
// and so forth with the rest of the tag buttons up to tag19_Button that sets title, "="
}
}
Next, in another Swift-file, instantiatedLandscapeButtonViewController, I have a similiar setup for the UIButtons with tag1 to tag30:
import UIKit
class instantiatedLandscapeButtonViewController: UIViewController {
#IBOutlet weak var tag1_Button: UIButton!
#IBOutlet weak var tag2_Button: UIButton!
#IBOutlet weak var tag3_Button: UIButton!
// .....
#IBOutlet weak var tag30_Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// additional landscape buttons, setup
tag1_Button.titleLabel?.textAlignment = .center
tag1_Button.contentHorizontalAlignment = .center
tag1_Button.titleLabel?.numberOfLines = 1
let str_tag1_Button = NSMutableAttributedString(string: "mc")
str_tag1_Button.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize: 10), range: NSMakeRange(0, 2))
str_tag1_Button.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(red: 251/255.0, green: 251/255.0, blue: 251/255.0, alpha: 1.0), range: NSMakeRange(0, 2))
tag1_Button.setAttributedTitle(str_tag1_Button, for: .normal)
// and so forth
}
}
Your code as it stands is dangerous and illegal:
extension UIButton {
override open func layoutSubviews() {
No! You cannot perform an override in an extension! The results can be unpredictable. The way to achieve a reliable circular button is to subclass UIButton, where override is legal, and use that subclass.
class MyCircularButton: UIButton {
override open func layoutSubviews() {
super.layoutSubviews()
let radius = min(bounds.width, bounds.height) / 2
layer.cornerRadius = radius
}
}
Now use a MyCircularButton instead of a plain UIButton wherever you want a circular button. I don't know that this will solve the issue you're having, but it is certainly a required first step.
I tested your remaining code like this, and it worked fine:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let tag1_Button = MyCircularButton()
tag1_Button.frame = CGRect(x: 100, y: 100, width: 40, height: 40)
tag1_Button.titleLabel?.textAlignment = .center
tag1_Button.contentHorizontalAlignment = .center
tag1_Button.titleLabel?.numberOfLines = 1
let str_tag1_Button = NSMutableAttributedString(string: "AC")
str_tag1_Button.addAttribute(.font, value: UIFont.systemFont(ofSize: 10), range: NSMakeRange(0, 2))
str_tag1_Button.addAttribute(.foregroundColor, value: UIColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0), range: NSMakeRange(0, 2))
tag1_Button.setAttributedTitle(str_tag1_Button, for: .normal)
tag1_Button.backgroundColor = UIColor(red: 40/255.0, green: 247/255.0, blue: 45/255.0, alpha: 1.0)
self.view.addSubview(tag1_Button)
}
}
Result:
I have created the UIButton programmatically and set the method to call when user touch on it using remote control. Below is my code.
import UIKit
class ViewController: UIViewController,VLCMediaPlayerDelegate,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var btnClick: UIButton!
#IBOutlet weak var clickBtn: UIButton!
#IBOutlet weak var myLbl: UILabel!
#IBOutlet weak var playBtn: UIButton!
#IBOutlet weak var zoomBtn: UIButton!
#IBOutlet weak var logoutBtn: UIButton!
var movieView: UIView! // Add VLC Player on movieView
var mediaPlayer: VLCMediaPlayer = VLCMediaPlayer() // VLC Media Player
var PlayButton = UIButton()
var isZoom:Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor( red: CGFloat(68/255.0), green: CGFloat(117/255.0), blue: CGFloat(196/255.0), alpha: CGFloat(1.0))
self.movieView = UIView()
self.movieView.backgroundColor = UIColor.black
self.movieView.frame = CGRect(x: self.view.frame.minX + 400, y: self.view.frame.minY, width: self.view.frame.size.width - 800, height: self.view.frame.height/2)
self.view.addSubview(self.movieView)
mediaPlayer.delegate = self
mediaPlayer.drawable = self.movieView
let url = "http://192.168.1.34:8852/out.ts"
let urls = URL(string: url)
let media = VLCMedia(url: urls!)
mediaPlayer.media = media
mediaPlayer.rate = 0
// mediaPlayer.play()
self.playButtonTapped(sender: mediaPlayer)
PlayButton = UIButton(type: .system)
PlayButton.setTitle("Play", for: .normal)
PlayButton.frame = CGRect(x: self.view.frame.midX - 100, y: self.view.frame.midY - 300, width: 200, height: 86) //midY-20
PlayButton.addTarget(self, action: #selector(pressButton), for: .touchUpInside)
// PlayButton.setImage(UIImage(named: "pause-button.png"/*"Pause-1.png"*/), for: .normal)
self.view.addSubview(PlayButton)
// self.view.bringSubview(toFront: PlayButton)
// self.view.sendSubview(toBack: mediaPlayer.drawable as! UIView)
}
//The target function
#objc func pressButton(){
print("Hello")
}
}
The issue is pressButton method never get called.
I found the issue was with ".touchUpInside" on tvOS, since that doesn't do what we might expect: we need to use ".PrimaryActionTriggered" instead.
Thank you all for your support.
What I want to happen is that the rectangle view will adjust to how long the label is. Here are my codes
#IBOutlet weak var rectangleView: UIView!
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let stringNumber = "123ewrqrqwerw4"
let numberFromString = Int(stringNumber)
rectangleView.frame = CGRect(x: 15, y: 100, width: self.view.frame.width * numberFromString, height: 50)
self.label.text = stringNumber
}
but my code is wrong.