i just want to modify the size of character of the UITextView. until now is possible to attach the string, but i Try to change the dimension: is not possible.
As i searched into the Forum i found that some people got it selecting Editable and deselecting it. Other people got it by selecting Selectable from the View properties. Then i tried this way... no way to change. Only Plain text.
import UIKit
#objc(TextControllerSwift) class TextControllerSwift: UIViewController {
var selectedMovie: String?
var textPlaying: String?
#IBOutlet weak var textMuseum: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
realPlay()
}
func playText(textSelect: String) {
textPlaying = textSelect
}
//Giving the time to Segue method to wakeup.
func realPlay(){
var textRoom: String?
//reading the file .txt
let path = NSBundle.mainBundle().pathForResource(textPlaying, ofType:"txt")
if (path != nil){
do {
textRoom= try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
//here i'm getting the string.
}
catch {/* ignore it */}
//i tried it these options...
textMuseum.editable=true
textMuseum.selectable=true
textMuseum!.text=""
//Got the text, now i put into UiView
textMuseum.font = UIFont(name: "Arial-Unicode", size: 50)
textMuseum.text=textMuseum.text.stringByAppendingString(String(textRoom!))
}}}
hmmm where am i getting wrong?
because i changed the textMuseum font. Should i free some Costraint on the UITextView Object put in the StoryBoard? also with the editable and selectable removed the result is the same. why?
thank you for every help.
EDIT:
Added Git Repository - No Working Video as i deleted this part. To see the problem just click on uisegmented "testo" and select play or the table.
https://github.com/sanxius/TryText.git
After reviewing your source code:
Make UITextView selectable: textMuseum.selectable = true
If you want to use custom font then do not forget it's file name to add it to Info.plist Fonts provided by application array.
Use existing font name. There is no font with name Arial-Unicode. Arial-Unicode.ttf is file name not font name.
You can find your font name by listing all loaded fonts with:
for familyName in UIFont.familyNames() {
for fontName in UIFont.fontNamesForFamilyName(familyName) {
print(fontName)
}
}
Also iOS has built-in Arial font that can be loaded by UIFont(name: "ArialMT", size: 50). So you do not need to add your Arial-Unicode.ttf.
Related
I'm developing a macOS rich-text editor that applies pre-defined style for each line of the text view.
To format the lines, I'm using NSAttributedString, then, I'm inserting that string into my UITextView. To make things easier, I'm using a tool called SwiftRichString.
My code looks like below. It's straight-forward and works fine.
import Cocoa
import SwiftRichString
import AppKit
class ViewController: NSViewController {
#IBOutlet var textView: NSTextView!
override func viewDidLoad() {
super.viewDidLoad()
// Format the string
let style = Style {
$0.font = NSFont(name: "Arial", size: 20)
$0.color = NSColor.black
$0.alignment = .center
}
let attributedText = "Hello World!".set(style: style)
// Add formatted string to the text view
textView.textStorage?.append(attributedText)
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
Current situation:
User is typing a formatted line. Then when user hits Return and types something, format of the new line returns back to the default style of the UITextView.
What I want:
User is typing a certain formatted line, then he hits Return. The next line should be formatted to another pre-defined style on-the-go.
Example:
User is typing the Title line. Current style is (Arial, bold, 20pt).
He hits Return.
Next line should be styled as Normal Text using a pre-defined style (Arial, 12pt).
Important Note:
In my above code, I was able to format the line easily because it's hard-coded. My real issue is, how can I instantly format the next line, because the next line will be entered by the user. The style should be applied to the next line before user begins writing it.
Okay, I just figured out how to use typingAttributtes to solve this question (thanks to #Larme for the hint).
// Define next attributes
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: NSColor.red,
.font: NSFont(name: "Arial", size: 12)!,
]
// Assign attributes to the text view typing attributes
textView.typingAttributes = attributes
Very easy!
Pardon off topic. If you're making a text editor, you may consider using a table view, where each text line is a cell - this is extra work for you as a programmer but it'll boost the performance significantly. That's how Xcode editor is built.
Maybe you might use optional func textViewDidChange(_ textView: UITextView)
https://developer.apple.com/documentation/uikit/uitextviewdelegate/1618599-textviewdidchange
and after the change, just parse the text, find new lines, split them and apply all styling you want
I would like to make my app appear in the UIActivityViewController for text sharing, like in Mail, iMessage, Notes, Gmail etc etc.
For example, when user tapback on selected text and hit the 'Share' button from any app like in the attachment:
I would like my app to appear in the UIActivityViewController and when the user selects my app, to launch it with the ability to handle that selected text.
So what I have tried:
Search in Apple documentation.
Searched for relevant UTI but I understood that the UTIs are used only for files and not for a simple NSString (Correct me if I'm wrong).
I have tried to implement Share Extension, but this is not the solution that i want, I don't need the post popup and moreover than that I need to launch my app after sharing like in Mail, Notes, iMessage does (Regarding to Apple documentation we can't launch the contain app through Share extension only through Today extension).
Of course, I have searched a lot in StackOverFlow.
So any solutions?
Thanks!
Assume that you already have some app.
Add Target File -> New -> Target. In
the left pane, select Application Extension from the iOS section,
choose Action extension, and click Next.
Set the Product Name. Make sure the Action Type is Presents user interface. Click Finish.
In the Project Navigator, expand the extension group and click on MainInterface.storyboard. Select the image view and replace it with UITextView. Create and bind #IBOutlet weak var to it.
Select Info.plist of the extension, navigate to NSExtension -> NSExtensionAttributes -> NSExtensionActivationRule. Change the NSExtensionActivationRule's type from String to Dictionary. With the dictionary expanded, click the + button next to it. This will add a child key. Set its name to NSExtensionActivationSupportsText, its type to Boolean, and the value to YES. This ensures that the action extension is only visible when at least one input item contains text.
Put this code to ActionViewController.swift:
_
import UIKit
import MobileCoreServices
class ActionViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Get the item[s] we're handling from the extension context.
var textFound = false
for item in self.extensionContext!.inputItems as! [NSExtensionItem] {
for provider in item.attachments! {
if provider.hasItemConformingToTypeIdentifier(kUTTypePlainText as String) {
// This is an plain Text.
weak var weakTextView = self.textView
provider.loadItem(forTypeIdentifier: kUTTypePlainText as String, options: nil, completionHandler: { (textItem, error) in
OperationQueue.main.addOperation {
if let strongTextView = weakTextView {
if let gotText = textItem as? String {
strongTextView.text = gotText
// do what you need with the text
}
}
}
})
textFound = true
break
}
}
if (textFound) {
// We only handle one text, so stop looking for more. You can do as you need.
break
}
}
}
#IBAction func done() {
// Return any edited content to the host app.
// This template doesn't do anything, so we just echo the passed in items.
self.extensionContext!.completeRequest(returningItems: self.extensionContext!.inputItems, completionHandler: nil)
}
}
I'm pretty new to iOS development and I was asking my self if it is possible to use localized strings from my "Localizable.strings" file directly into the storyboard.
For example in Android you can do it from the XML file like this:
android:text="#string/notConnected"
I understood that you can make a localized version of the storyboard, but having different strings files and different storyboards looks pretty ugly to me.
So is it possible to have only strings files and use what I need into the storyboard? Preferably without setting it from code?
EDIT:
This is practically what I want to do:
So is this possible? Is there a legit way to call a string from there like in Android?
I think being able to localise Strings in the storyboard is of significant advantage. I don't agree with #elk_cloner that hooking up IBOutlets for every UILabel is the way forward.
One way of getting it to work is using an #IBInspectable property on a UILabel subclass:
class LocalisableLabel: UILabel {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
text = NSLocalizedString(key, comment: "")
}
}
}
In the storyboard set the custom class:
In the attributes inspector the localisedKey field will appear and you can just add your key here.
That's it!
EDIT:
You can localise UIButtons the same way, BUT if the text in the storyboard's title field differs from the localised String (which it will in other languages) the setting of the title will animate.
To fix this, put the setTitle in a performWithoutAnimation block:
class LocalisableButton: UIButton {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
UIView.performWithoutAnimation {
setTitle(key.localized, for: .normal)
layoutIfNeeded()
}
}
}
}
In addition to Leon's answer, you can get rid of the need for an explicit subclass by using an extension:
extension UILabel {
#IBInspectable var localizableText: String? {
get { return text }
set(value) { text = NSLocalizedString(value!, comment: "") }
}
}
According to your requirement it's not possible but
You don't need different storyboards for localization
Suppose you want to localize a label string.
Draw and outlet and change text using
mylabel.text = nsLocalizedString("THIS_IS_MY_STRING",nil);
Of course in your localization file there will be a line.You must have different files for different language.Suppose you have a file for english and there must be a line.
"THIS_IS_MY_STRING" = "This is my string";
When you compile your app, that function will use mapping to localize your app.
Edit:
If you want detail information please have a look at these tutorials
internationalization-tutorial-for-ios-2014
and ios-localization-tutorial
There are some online script(e.g localize.py) which will help you to automatically search all of your code and find out nslocalizedString function and make lines in your localizableString files. like this.
"THIS_IS_MY_STRING" = "THIS_IS_MY_STRING"
and later on you just have to write actual string there. :)
Make a button class and set #IBInspectable attribute to the button class
class Button: UIButton {
#IBInspectable public var referenceText: String = "" {
didSet {
self.setTitle(NSLocalizedString(referenceText, comment: ""), for: .normal)
}
}
}
Then in the storyboard you can set referenceText
The button text will be "Sign In"
Another possible way is to localize the storyboard and simply change the values for labels and buttons directly on the .string file.
First select the storyboard, and click on localize:
Then you'll be able to select the languages you want.
This way you'll be able to continue developing on your language of choice and simply edit the .string file that is generated
for button
extension UIButton {
#IBInspectable var localizableText: String? {
get { return titleLabel?.text }
set(value)
{
setTitle(NSLocalizedString(value!, comment: ""), for: .normal)
}}}
I have a UIPrintInteractionController that is created programatically. It is set to pull a pdf from my servers, and print said pdf. My question is how can I change the font of the view. I already have set the navbar font in my app delegate (so the font appears on all views), but this doesn't apply to the view. Any help is greatly appreciated. Thanks!
I figured it out. Create an extension of UILabel like so
extension UILabel {
var substituteFontName : String {
get { return self.font.fontName }
set { self.font = UIFont(name: newValue, size: self.font.pointSize) }
}
}
The in AppDelegate.swift, use this extension to change the font of every label in the entire application, INCLUDING the UIPrinterInteractionController.
UILabel.appearance().substituteFontName = "Font Name Here"
Killed two birds with one stone.
Is there a way to add a target to a specified word from an UITextView? For example.
I want to add a target to a hash-tagged word from a UITextView.
I'm using a function to get an array with the hash-tagged words from the textview, but I don't know how to add them a target, or a tap-gesture.
You can use an attributed string to set the text in the text view. That attributed string uses link attributes (NSLinkAttributeName with a URL value of your choice) in the range of your target hash-tagged words. You need to search the text for your hash-tagged words and add the appropriate link attributes. You probably want to create the link URLs to have a custom scheme and include information about the hash-tagged word. When one of the links is tapped you get a delegate callback from the text view.
I had the same question recently and I found a solution that fit my needs. It's not perfect but maybe it will help:
I decided to go for a whole text button with specific style around my target element. In a user experience way, user may be inclined to touch the styled word.
#IBOutlet weak var stringBtn: UIButton!
override func viewWillAppear(animated: Bool) {
let string = "string with #tag" as NSString
var attributedString = NSMutableAttributedString(string: string as String)
let firstAttributes = [NSUnderlineStyleAttributeName: 1, NSForegroundColorAttributeName: UIColor.whiteColor()]
attributedString.addAttributes(firstAttributes, range: string.rangeOfString("#tag"))
stringBtn.setAttributedTitle(attributedString, forState: .Normal)
//Add target to your button
}