I am getting only these 3 options every time
while my whole code is working any help will be appreciated.
let selections = pdfView.currentSelection?.selectionsByLine()
guard (selections?.first?.pages.first) != nil else { return }
selections?.forEach({ selection in
let newAnnotation = PDFAnnotation(bounds: selection.bounds(for: pdfView.currentPage!) ,forType: PDFAnnotationSubtype.highlight ,withProperties: nil)
// Add additional properties to the annotation
newAnnotation.color = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
self.pdfView.currentPage?.displaysAnnotations = true
self.pdfView.currentPage?.addAnnotation(newAnnotation)
})
I'm struggling with this question as well, but cannot find any option to add it to PDFView in iOS.
In the end I stumbled on a general method of adding menu-items via the shared UIMenuController class.
let menuItem = UIMenuItem(title: "Highlight", action: #selector(HighLightHandler.highlightSelection(_:)))
UIMenuController.shared.menuItems = [menuItem]
And handle any the highlight:
#objc func highlightSelection(_ sender: UIMenuItem) {
//put your highlighting code here
}
Related
So I am making a quiz app, and I am using the following code to display to the user if the answer is correct or wrong.
The app looks like this:
Image here
This is the code to display:
#IBAction func checkAnswer(_ sender: UIButton) {
if let question = currentQuestion, let answer = sender.titleLabel?.text {
if (question.validateAnswer(to: answer)) {
score.incrementCorrectAnswers()
currentScore = currentScore + 1
feedbackLabel.textColor = UIColor(red:0.15, green:0.61, blue:0.61, alpha:1.0)
feedbackLabel.text = "Correct!"
scoreLabel.text = "\(currentScore)"
sender.backgroundColor = hexStringToUIColor(hex: "213F4B")
} else {
score.incrementIncorrectAnswers()
feedbackLabel.textColor = UIColor(red:0.82, green:0.40, blue:0.26, alpha:1.0)
feedbackLabel.text = "Wrong, correct answer is: \n\(currentQuestion!.getAnswer())"
sender.shake()
sender.backgroundColor = hexStringToUIColor(hex: "3F2F4B")
}
answer1Button.isEnabled = false
answer2Button.isEnabled = false
answer3Button.isEnabled = false
answer4Button.isEnabled = false
nextQuestionButton.isEnabled = true
feedbackLabel.isHidden = false
}
}
When using this, if the user tap the wrong button, the button turns red, and if the user taps the correct button, the button turns green. How can I make it so if the user taps the wrong button, the answer on the correct button turns green at the same time as the wrong one goes red? Let me know if any other code from project is necessarily.
You could loop through all UIButton's and check for sender.titleLabel?.text like this:
for view in self.view.subviews as [UIView] {
if let btn = view as? UIButton {
if btn.titleLabel?.text == currentQuestion!.getAnswer() {
btn.backgroundColor = hexStringToUIColor(hex: "213F4B") // Green Color
}
}
}
I'm not on my computer so won't be able to test it, so try it out and let me know how it works.
I have a UIButton at bottom of the screen and when the user types in UITextView that button gets attached to the keypad (input accessory view) like the screenshot I have attached (violet arrow mark). Now once the keyboard is dismissed then I want this button to be at the bottom of the screen instead of the input accessory view (check yellow arrow mark flow).
Here is the code I used
override func viewDidLoad() {
super.viewDidLoad()
confirmButtonUI()
subscribeToShowKeyboardNotifications()
// Do any additional setup after loading the view.
}
func confirmButtonUI() {
confirmButton.layer.cornerRadius = 20.0
confirmButton.layer.shadowRadius = 1.0
confirmButton.layer.shadowColor = UIColor(displayP3Red: 33/255, green: 68/255, blue: 27/255, alpha: 0.18).cgColor
confirmButton.layer.backgroundColor = UIColor(displayP3Red: 164/255, green: 208/255, blue: 208/255, alpha: 1).cgColor
confirmButton.isEnabled = false
confirmButton.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
confirmButton.layer.shadowOpacity = 1.0
confirmButton.layer.masksToBounds = false
}
func subscribeToShowKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector:
#selector(keyboardWillShow(_:)), name:
UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector:
#selector(keyboardWillHide(_:)), name:
UIResponder.keyboardWillHideNotification, object: nil)
}
#objc func keyboardWillShow(_ notification: Notification) {
let userInfo = notification.userInfo
confirmButton.layer.cornerRadius = 0.0
othersTextField.inputAccessoryView = confirmButton
let keyboardSize = userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue
_ = keyboardSize.cgRectValue.height
let animationDuration = userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: animationDuration) {
self.view.layoutIfNeeded()
}
}
#objc func keyboardWillHide(_ notification: Notification) {
othersTextField.inputAccessoryView = nil
confirmButtonBottomConstrains.constant = 57 //Crash here
let userInfo = notification.userInfo
let animationDuration = userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: animationDuration) {
self.view.layoutIfNeeded()
}
}
In this method its crashing on this line " confirmButtonBottomConstrains.constant = 57 "
What i was doing is once the keyboard is dismissing am making inputAccessoryView as nil and then am trying to use the bottom nslayout constraint for the button to set as 57 (like i set in UI) but this line crashing with following message
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Please help me to solve this
Problem
You haven't provided details about whether the view is setup programmatically or in a storyboard. I am assuming it was a storyboard (since I do not see any view initialization).
Also, I am not sure how you got the button to stick as an inputAccessoryView. I couldn't replicate this behavior. In your case, setting a view that is already part of the view hierarchy as an accessory view might be causing the undocumented behavior where existing constraints are removed.
Solution
Instead of using the same button, you can very easily create a new button and assign it as an inputAccessoryView to your UITextField / UITextView.
This would eliminate problems with missing constraints since the original view is never changed.
It would look something like this, (in addition to your disabled button):
Code to setup input accessory view:
override func viewDidLoad() {
super.viewDidLoad()
setupInputAccessory()
othersTextField.delegate = self
}
func setupInputAccessory(){
let width = UIScreen.main.bounds.width
let frame = CGRect(x: 0, y: 0, width: width, height: 44.0)
let btn = UIButton(frame: frame)
btn.backgroundColor = UIColor.purple
btn.setTitleColor(UIColor.white, for: .normal)
btn.setTitle("Confirm", for: .normal)
btn.addTarget(self, action: #selector(accessoryConfirmTapped), for: .touchUpInside)
othersTextField.inputAccessoryView = btn
}
#objc func accessoryConfirmTapped(){
othersTextField.resignFirstResponder()
}
Notes
The above is a code snippet in addition to your existing code. However, with this approach I have removed the following from your code.
Changing the othersTextField.inputAccessoryView in keyboard events.
Confirm Button bottom constraint.
But the gist of it is, I have two separate buttons. One that is setup by the storyboard and the other setup in code and attached to the TextField. I do not share the button with the controller's view and as the input accessory.
I have the complete solution in a GitHub Repo if you want to check it out further.
I’m using left side menu from jonkykong/SideMenu this framework. Here i need to change background view colour alpha value while open(means click on button) the side menu and when i close the side menu i need back the original background colour.
for that I have tried two methods:
Method 1):
func sidemenuOpenCloseColorChang(){
let menu = storyboard!.instantiateViewController(withIdentifier: "UISideMenuNavigationController") as! UISideMenuNavigationController
var set = SideMenuSettings()
set.statusBarEndAlpha = 0
set.presentationStyle = SideMenuPresentationStyle.menuSlideIn
set.presentationStyle.presentingEndAlpha = 0.5
set.menuWidth = min(view.frame.width, view.frame.height) * 0.90
//menu.sideMenuManager.addScreenEdgePanGesturesToPresent(toView: self.view)
menu.settings = set
//SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: view)
SideMenuManager.default.leftMenuNavigationController = menu
}
getting below error:
Use of unresolved identifier 'SideMenuSettings'
Use of unresolved identifier 'SideMenuPresentationStyle'
Value of type 'SideMenuManager' has no member 'leftMenuNavigationController'
Method 2): using UISideMenuNavigationControllerDelegate Metod
#IBAction func sideMenubtn(_ sender: Any) {
view?.backgroundColor = UIColor(white: 1, alpha: 0.9)
}
extension ProfileViewController : UISideMenuNavigationControllerDelegate {
private func sideMenuWillDisappear(menu: UISideMenuNavigationControllerDelegate, animated: Bool) {
//*do the color thing*
print("sidemenu disappear")
view?.backgroundColor = UIColor.white
}
Nothing worked for me, please help me in this code.
Thanks in advance
I work on an iOS application that implements a UITabBarController with 5 icons connected. The whole project is made via Storyboard. As I want to give the option for 4 themes to the user, which thing I do in a static tableView, I came across an issue.
When the user changes theme, the previously instantiated via the tabBar view controllers do not update to the theme change because they exist before the theme update. Can I somehow dismiss them and create new instances of the same view controller classes upon the didSelect method of the UITabBar delegate?
Am I approaching the issue correctly? Any help would be much appreciated!
Thanks you in advance for your help.
class MainTabController: UITabBarController
{
override func viewDidLoad()
{
super.viewDidLoad()
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem)
{
let theme = UserDefaults.standard.string(forKey: "selectedColor")
print(theme!)
for vc in self.viewControllers!
{
if (theme == "default")
{
vc.view.backgroundColor = UIColor(red: 0xF9 , green: 0xF7 , blue: 0xF7)
}else if (theme == "theme1")
{
vc.view.backgroundColor = UIColor(red: 0x1F , green: 0xFF, blue: 0xFF)
}else if (theme == "theme2")
{
vc.view.backgroundColor = UIColor(red: 0xE3 , green: 0xFD, blue: 0xFD)
}else if (theme == "theme3")
{
vc.view.backgroundColor = UIColor(red: 0x3E, green: 0xC1, blue: 0xD3)
}
}
}
}
example of implementing in each view controller:
override func viewDidLoad()
{
let theme = UserDefaults.standard.string(forKey: "selectedColor")
print(theme!)
if (theme == "default")
{
outerView.backgroundColor = UIColor(red: 0xF9 , green: 0xF7 , blue: 0xF7)
}else if (theme == "theme1")
{
outerView.backgroundColor = UIColor(red: 0x1F , green: 0xFF, blue: 0xFF)
}else if (theme == "theme2")
{
outerView.backgroundColor = UIColor(red: 0xE3 , green: 0xFD, blue: 0xFD)
}else if (theme == "theme3")
{
outerView.backgroundColor = UIColor(red: 0x3E, green: 0xC1, blue: 0xD3)
}
}
Inside didSelect you can access the tab VCs and change them as you like ( inside any VC in the tab )
for vc in self.tabBarController!.viewControllers! {
vc.view.backgroundColor = UIColor.red
// if you want to set a property
if let other = vc as? OtherViewController {
// change here
}
}
//
if you want this code inside the tabBar custom class
for vc in self.viewControllers! {
vc.view.backgroundColor = UIColor.red
// if you want to set a property
if let other = vc as? OtherViewController {
// change here
}
}
//
after your edit , you need to either create a protocol containing the outerView and conform to this protocol in every VC or cast to the VC and change it's property
Create custom UITabBarController class and in it's viewDidLoad add :
for vc in self.viewControllers! {
vc.view.backgroundColor = .....
}
Now link this custom class to the Storyboard's UITabBarController.
Update :
You are getting the value from UserDefaults incorrectly.
UserDefaults.standard.string(forKey: "selectedColor")
It should be :
UserDefaults.standard.object(forKey: "selectedColor")
The solution to my problem was really simple but only after many hours of searching!
I had to put all my code that is editing the view in viewDidAppear instead of viewDidLoad because viewDidLoad is running only on the first time in contrast with
viewDidAppear which is called every time the user presses this particular tab.
Thank you all for your fast answers!
When using a UISegmentedControl, I have a problem fitting all the labels, precisely in Japanese.
I did not notice the same issue with the other language I used at this point.
Here is my code:
interfaceChoice = UISegmentedControl(items: ["白黒モード", "緑赤青・モード"])
for i in 0..<interfaceChoice.subviews.count {
interfaceChoice.subviews[i].tintColor = localColor
for subSubView in interfaceChoice.subviews[i].subviews {
if subSubView is UILabel {
(subSubView as! UILabel).adjustsFontSizeToFitWidth = true
}
}
}
I would hope the line ..adjustsFontSizeToFitWidth.. would sort things out, but it does not work as one can see in the picture below.
Anyone has an idea as what I am doing wrong?
Storyboard example
This is how I did it.
In a story board, drag and drop a segmented control into the title area of the view controller.
Link the segmented control to an IBOutlet in the view controller.
This code
class ViewController: UIViewController {
#IBOutlet weak var interfaceChoice: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
interfaceChoice.removeAllSegments()
interfaceChoice.insertSegment(withTitle: "白黒モード", at: 0, animated: false)
interfaceChoice.insertSegment(withTitle: "緑赤青・モード", at: 1, animated: false)
interfaceChoice.selectedSegmentIndex = 0
let font = UIFont.boldSystemFont(ofSize: 16)
interfaceChoice.setTitleTextAttributes([NSFontAttributeName: font], for: .normal)
interfaceChoice.tintColor = UIColor(red: 27/CGFloat(255), green: 77/CGFloat(255), blue: 102/CGFloat(255), alpha: 1.0)
}
}
Note: I won't pretend to know exactly why it's not behaving for you, but I hope this can help. If it is absolutely imperative to fix your exact situation, I think we might need more information.
Pure code example
This produces the same result as setting it up in the storyboard.
class ViewController: UIViewController {
var interfaceChoice: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
interfaceChoice = UISegmentedControl(items: ["白黒モード", "緑赤青・モード"])
interfaceChoice.selectedSegmentIndex = 0
let font = UIFont.boldSystemFont(ofSize: 16)
interfaceChoice.setTitleTextAttributes([NSFontAttributeName: font], for: .normal)
interfaceChoice.tintColor = UIColor(red: 27/CGFloat(255), green: 77/CGFloat(255), blue: 102/CGFloat(255), alpha: 1.0)
self.navigationItem.titleView = interfaceChoice
}
}