, используя ответ @ Andriy, и этот ответ i удалось установить высоту contentSize в WKWebView и изменить его высоту.
здесь полный быстрый код 4:
var neededConstraints: [NSLayoutConstraint] = []
@IBOutlet weak var webViewContainer: UIView!
@IBOutlet weak var webViewHeight: NSLayoutConstraint! {
didSet {
if oldValue != nil, oldValue.constant != webViewHeight.constant {
view.layoutIfNeeded()
}
}
}
lazy var webView: WKWebView = {
var source = """
var observeDOM = (function(){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
eventListenerSupported = window.addEventListener;
return function(obj, callback){
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
callback();
});
// have the observer observe foo for changes in children
obs.observe( obj, { childList:true, subtree:true });
}
else if( eventListenerSupported ){
obj.addEventListener('DOMNodeInserted', callback, false);
obj.addEventListener('DOMNodeRemoved', callback, false);
}
};
})();
// Observe a specific DOM element:
observeDOM( document.body ,function(){
window.webkit.messageHandlers.sizeNotification.postMessage({'scrollHeight': document.body.scrollHeight,'offsetHeight':document.body.offsetHeight,'clientHeight':document.body.clientHeight});
});
"""
let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let controller = WKUserContentController()
controller.addUserScript(script)
controller.add(self, name: "sizeNotification")
let configuration = WKWebViewConfiguration()
configuration.userContentController = controller
let this = WKWebView(frame: .zero, configuration: configuration)
webViewContainer.addSubview(this)
this.translatesAutoresizingMaskIntoConstraints = false
this.scrollView.isScrollEnabled = false
// constraint for webview when added to it's superview
neededConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[web]|",
options: [],
metrics: nil,
views: ["web": this])
neededConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[web]|",
options: [],
metrics: nil,
views: ["web": this])
return this
}()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
_ = webView // to create constraints needed for webView
NSLayoutConstraint.activate(neededConstraints)
let url = URL(string: "https://www.awwwards.com/")!
let request = URLRequest(url: url)
webView.load(request)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let body = message.body as? Dictionary,
let scrollHeight = body["scrollHeight"],
let offsetHeight = body["offsetHeight"],
let clientHeight = body["clientHeight"] {
webViewHeight.constant = scrollHeight
print(scrollHeight, offsetHeight, clientHeight)
}
}
С условными переходами jc
(переход при переносе) или jnc
(переход при отсутствии переноса).
Или вы можете сохранить флаг переноса,
;; Intel syntax
mov eax, 0
adc eax, 0 ; add with carry
Однако ассемблер x86 выделил быстрые команды тестирования флага ALU с именем SETcc, где cc является желаемым флагом ALU. Итак, вы можете написать:
setc AL //will set AL register to 1 or clear to 0 depend on carry flag
or
setc byte ptr [edx] //will set memory byte on location edx depend on carry flag
or even
setc byte ptr [CarryFlagTestByte] //will set memory variable on location CarryFlagTestByte depend on carry flag
С помощью инструкции SETcc вы можете проверять такие флаги, как перенос, ноль, знак, переполнение или четность, некоторые инструкции SETcc позволяют проверять два флага одновременно.
РЕДАКТИРОВАТЬ: Добавлен простой тест, сделанный в Delphi, чтобы не сомневаться в термине fast
procedure TfrmTest.ButtonTestClick(Sender: TObject);
function GetCPUTimeStamp: int64;
asm
rdtsc
end;
var
ii, i: int64;
begin
i := GetCPUTimeStamp;
asm
mov ecx, 1000000
@repeat:
mov al, 0
adc al, 0
mov al, 0
adc al, 0
mov al, 0
adc al, 0
mov al, 0
adc al, 0
loop @repeat
end;
i := GetCPUTimeStamp - i;
ii := GetCPUTimeStamp;
asm
mov ecx, 1000000
@repeat:
setc al
setc al
setc al
setc al
loop @repeat
end;
ii := GetCPUTimeStamp - ii;
caption := IntToStr(i) + ' ' + IntToStr(ii));
end;
Цикл (1M итераций), использующий инструкцию setc , более чем в 5 раз быстрее, чем цикл с adc ] инструкция.
РЕДАКТИРОВАТЬ: Добавлен второй тест, результаты которого сохраняются в регистре AL совместно с регистром CL, чтобы быть более реалистичным.
procedure TfrmTestOtlContainers.Button1Click(Sender: TObject);
function GetCPUTimeStamp: int64;
asm
rdtsc
end;
var
ii, i: int64;
begin
i := GetCPUTimeStamp;
asm
xor ecx, ecx
mov edx, $AAAAAAAA
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
end;
i := GetCPUTimeStamp - i;
ii := GetCPUTimeStamp;
asm
xor ecx, ecx
mov edx, $AAAAAAAA
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
end;
ii := GetCPUTimeStamp - ii;
caption := IntToStr(i) + ' ' + IntToStr(ii);
end;
Рутинная часть с инструкцией SETcc все еще быстрее примерно на 20%.
sbb %eax,%eax
сохранит -1 в eax, если флаг переноса установлен, 0 - если он очищен. Нет необходимости предварительно очищать eax до 0; вычитание eax из самого себя сделает это за вас. Эта техника может быть очень мощной, поскольку вы можете использовать результат как битовую маску для изменения результатов вычислений вместо использования условных переходов.
Вы должны знать, что проверять флаг переноса можно только в том случае, если он был установлен арифметикой, выполненной ВНУТРИ блока inline asm. Вы не можете проверить флаг переноса вычислений, которые были выполнены в коде C, потому что есть всевозможные способы, которыми компилятор может оптимизировать/переупорядочить вещи, которые уничтожат флаг переноса.