Это ответ Sajjad Hussain Khan , переписанный для iOS без атрибутов non-Swifty NS-prefixed и более чистого кода.
import Security
class KeychainService {
class func updatePassword(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let status = SecItemUpdate(modifierQuery(service: service, account: account), [kSecValueData: dataFromString] as CFDictionary)
checkError(status)
}
class func removePassword(service: String, account: String) {
let status = SecItemDelete(modifierQuery(service: service, account: account))
checkError(status)
}
class func savePassword(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecValueData: dataFromString]
let status = SecItemAdd(keychainQuery as CFDictionary, nil)
checkError(status)
}
class func loadPassword(service: String, account: String) -> String? {
var dataTypeRef: CFTypeRef?
let status = SecItemCopyMatching(modifierQuery(service: service, account: account), &dataTypeRef)
if status == errSecSuccess,
let retrievedData = dataTypeRef as? Data {
return String(data: retrievedData, encoding: .utf8)
} else {
checkError(status)
return nil
}
}
fileprivate static func modifierQuery(service: String, account: String) -> CFDictionary {
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecReturnData: kCFBooleanTrue]
return keychainQuery as CFDictionary
}
fileprivate static func checkError(_ status: OSStatus) {
if status != errSecSuccess {
if #available(iOS 11.3, *),
let err = SecCopyErrorMessageString(status, nil) {
print("Operation failed: \(err)")
} else {
print("Operation failed: \(status). Check the error message through https://osstatus.com.")
}
}
}
}
Создайте элемент span, установите для innerHTML Span значение «Hello World».
Получите offsetHeight диапазона.
var span = document.createElement("span");
span.innerHTML="Hello World"; //or whatever string you want.
span.offsetHeight // this is the answer
обратите внимание, что вы должны установить стиль шрифта диапазона в соответствии со стилем шрифта текстового поля.
Ваш пример НИКОГДА не будет работать, потому что innerHTML и значение являются строками. String не определяет offsetWidth.
Если вы хотите получить высоту выделенного текста внутри текстовой области, используйте selectionStart / selectionEnd, чтобы найти выделенный текст в текстовой области.
element.scrollHeight, вероятно, заслуживает изучения.
Если бы я собирался подойти к этому (а я это вообще не тестировал), я бы установил высоту текстового поля на 1 пиксель, измерьте высоту прокрутки, а затем сбросил бы высоту текстового поля.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
http://www.quirksmode.org/dom/range_intro.html извините, что я не могу больше помочь.
Проблема с вашим примером заключается в том, что встроенный текст не имеет высоты, он имеет только высоту строки, для того, чтобы он имел высоту, он должен быть в режиме блока отображения, так что все строки добавляются в блок текста, даже тогда все зависит от ширины поля и размера шрифта, font-family etc.
ItzWarty предлагает получить выделение текста и поместить его в div, который имеет тот же шрифт и ширину, что и textarea, который имеет блок отображения и позволяет получить его высоту.