While editing the content of webview , scrollview won't move upwards and keyboard hides the lines - iphone

I am developing an app as like rich editor text and as i have wrote the text on editable web view but keyboard hides the lines. I am also using some javascript coding but not succeeded.
this.updateOffset = function() {
try{
var sel = window.getSelection();
range = sel.getRangeAt(0);
if(this.tmpSpan==null){
this.tmpSpan = document.createElement('span');
}
range.insertNode(this.tmpSpan);
this.yOffset = this.tmpSpan.offsetTop;
this.xOffset = this.tmpSpan.offsetLeft;
this.tmpSpan.parentNode.removeChild(this.tmpSpan);
}
catch(exc){
log('updateOffset:' + exc.toString());
}
}
// eContent is the div with 'contenteditable', while visibleHeight is an int, set from objective-c (depending on where the webview is positioned, keyboard height and screen height)
this.scrollToVisible = function(){
try {
if(this.eContent.clientHeight>this.visibleHeight){
this.updateOffset();
if(this.yOffset<window.pageYOffset){
window.scrollTo(0, this.yOffset);
}
else if(this.yOffset-window.pageYOffset>this.visibleHeight){
window.scrollTo(0, this.yOffset-this.visibleHeight);
}
}
}
catch (exc){
log('scrollToVisible: ', exc.toString());
}
}
Please suggest what we should do.

Related

SwiftUI Prevent user from tapping button while entering data

If the user clicks the button while editing the TextField (cursor flashing) in DataPtView, the app crashes.
In a list cell, I have the button, which impacts the view that is also shown in the cell.
Here's a snippet, iPad specific.
CellView:
VStack{
Button("TagOut"){
self.tagOut.toggle()
}
if self.tagOut {
TagOutView(question: question)
}
if !self.tagOut{
if question.type == "Y/N"{
YesOrNoView(question: question)
} else if question.type == "DataPt"{
DataPtView(question: question)
} else {
RecordEntryView()
}
...
DataPtView:
...
TextField("Data: ", text: $collectedData)
.onReceive(Just(collectedData)) {value in
let filtered = value.filter {"01234567890-".contains($0)}
if filtered != value{
self.invalidCollectedData = true
} else {
self.invalidCollectedData = false
}
}
...
I'm also using an AdaptsToKeyboard ViewModifier for when CellView is covered by the keyboard.
move-textfield-up-when-the-keyboard-has-appeared-in-swiftu
How do I prevent this from happening? If user hides the keyboard before clicking the button, everything is fine, but that isn't intuitive.
What if you try to check if your modifier height is greater than 0 and based on this handle the button click. In your cell view define:
#State var keyboardHeight: CGFloat = 0
Change your AdaptsToKeyboardModifier to have binding var inside it:
struct AdaptsToKeyboard: ViewModifier {
#Binding var currentHeight: CGFloat = 0
...
}
Now you need to initialize your modifier with the following constructor:
.modifier(AdaptsToKeyboard(currentHeight: $keyboardHeight))
Now you have two options to handle the button press:
To disable the button interaction:
Button("TagOut"){
self.tagOut.toggle()
}.disabled(keyboardHeight > 0)
To ignore the press:
Button("TagOut") {
if self.keyboardHeight == 0 {
self.tagOut.toggle()
}
}

WKWebView on macOS cuts off top

I placed a WKWebView inside a NSView with a y coordinate > 0. After loading a page (no matter which one) it either immediately cuts off the top or it shows the top for a second and then jumps down the page (by doing so cutting off the top).
What's more is that when I scroll up I get a glimpse of the top portion but it bounces back not allowing me to actually scroll to the very top.
No changes have been made to the WKWebView. What I noticed is, that the smaller y the smaller the portion which is cut off.
The WKWebView has been added via the Interface Builder.
How can I make the WKWebView show the top of the website? I'm using Swift.
This is what it looks like:
This is what the actual website looks like (notice the visible navigation section):
Okay, I had the same problem as you! Check your view's frame on construction and, if it's not starting at 0,0, make sure that the parent view doesn't auto resize the subviews. I tried to keep my code sample to the bare minimum. (note that webConfig.AllowsAirPlayForMediaPlayback isn't required in this sample)
Here's a working example. You can switch the view to be full frame in the window or positioned as a smaller view in the parent. I set the window to be 1024x768 in IB.
You can easily convert this code to Swift.
The key is to not autoresize the subviews if the view is being placed at an offset other than 0,0.
quick sample:
//#define USE_FULL_WINDOW // uncomment this to fit webview full window
using System;
using AppKit;
using Foundation;
using WebKit;
using CoreGraphics;
using System.Diagnostics;
namespace WkWebTest
{
public class MediaView : NSView
{
private WKWebView webView;
public MediaView(CGRect frame)
: base(frame)
{
#if USE_FULL_WINDOW
this.AutoresizesSubviews = true;
this.AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;
#endif
WKWebViewConfiguration webConfig = new WKWebViewConfiguration();
webConfig.AllowsAirPlayForMediaPlayback = true;
this.webView = new WKWebView(new CGRect(0, 0, frame.Width, frame.Height), webConfig);
this.webView.AutoresizesSubviews = true;
this.webView.AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;
this.AddSubview(this.webView);
string url = "http://www.apple.com";
Debug.WriteLine("LoadUrl: " + url);
var request = new NSUrlRequest(new NSUrl(url));
this.webView.LoadRequest(request);
}
public override bool IsFlipped { get { return true; } }
}
public partial class ViewController : NSViewController
{
private MediaView mediaView;
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
#if USE_FULL_WINDOW
float mediaViewLeft = 0;
float mediaViewTop = 0;
nfloat mediaViewWidth = View.Frame.Width;
nfloat mediaViewHeight = View.Frame.Height;
#else
float mediaViewLeft = 511;
float mediaViewTop = 112;
nfloat mediaViewWidth = 475;
nfloat mediaViewHeight = 548;
#endif
this.mediaView = new MediaView(new CGRect(mediaViewLeft, mediaViewTop, mediaViewWidth, mediaViewHeight));
this.View.AddSubview(mediaView);
}
// boiler plate code generated by Xamarin
public override NSObject RepresentedObject
{
get
{
return base.RepresentedObject;
}
set
{
base.RepresentedObject = value;
// Update the view, if already loaded.
}
}
}
}

What control to use to capture image from camera and show on ui as thumbnail with events xamarin ios

I have created a view like this in my xamarin iOS mobile project.
User will be able to click on the capture images button to take a picture and set the image property of the image view. I would like to know how can i allow the user longpress a image (after it has been captured) and popup a message box to delete the image.
I have tried what Sameer has suggested in his comment like so in my ViewDidLoad
var gestureRecognizer = new UILongPressGestureRecognizer();
gestureRecognizer.AddTarget(() => ButtonLongPressed(gestureRecognizer));
img1.AddGestureRecognizer(gestureRecognizer);
img2.AddGestureRecognizer(gestureRecognizer);
When i click and hold on the image nothing happens. I have added these image views via the designer.
After a little more research and using the comment from #Junior Jiang - MSFT. I have made a bit progress but i would like to know which UIImage view has been clicked.
Heres my current code:
public JobImagesViewController(Job passedInCurrentJob) : base("JobImagesViewController", null)
{
currentJob = passedInCurrentJob;
uIImageViews = new List<UIImageView>();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
uIImageViews.Add(img1);
uIImageViews.Add(img2);
uIImageViews.Add(img3);
uIImageViews.Add(img4);
uIImageViews.Add(img5);
uIImageViews.Add(img6);
uIImageViews.Add(img7);
uIImageViews.Add(img8);
uIImageViews.Add(img9);
uIImageViews.Add(img10);
InitialiseImageGrid();
// Add a Save button to the navigation bar
this.NavigationItem.SetRightBarButtonItem(
new UIBarButtonItem("Save", UIBarButtonItemStyle.Done, (sender, args) =>
{
//TODO if else block with all logic to check if there are images etc.
//TODO prompt user and ask if they would like to save images.
UIAlertView alert = new UIAlertView("Save Images?", "Save images against the Job?", null, "Yes", new string[] { "No" });
alert.Clicked += (s, e) =>
{
if (e.ButtonIndex == 0) // Yes clicked
{
SaveJobImages();
}
};
alert.Show();
}), true);
}
[Export("ImageLongPressed:")]
public void ImageLongPressed(UILongPressGestureRecognizer gestureRecognizer)
{
if (gestureRecognizer.State != UIGestureRecognizerState.Began)
{
return;
// Needed because selector is executed twice, because Long-press gestures are continuous
}
// Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image
UIAlertView alert = new UIAlertView("Delete this image ?" , "Are you sure you want to delete this image?", null, "Yes", new string[] { "No" });
alert.Clicked += (s, e) =>
{
if (e.ButtonIndex == 0) // 'Accept' clicked
{
// TODO how to get the image which has been clicked??
}
};
alert.Show();
}
private void InitialiseImageGrid()
{
_imageList = DataAccess.GetImages(currentJob.jobAddressID);
var imageBytes = _imageList.Select(x => x.ImageBytes).ToList();
var gestureRecognizer = new UILongPressGestureRecognizer(this, new ObjCRuntime.Selector("ImageLongPressed:"));
gestureRecognizer.AddTarget(() => ImageLongPressed(gestureRecognizer));
// Populate the image views.
// TODO need to find a way to assign it to every imageview on the view without looping maybe linq???
int i = 0;
foreach (var item in imageBytes)
{
var imagedata = NSData.FromArray(item);
var img = UIImage.LoadFromData(imagedata);
if (uIImageViews != null && uIImageViews.Count > i)
{
uIImageViews[i].UserInteractionEnabled = true;
uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
uIImageViews[i].Image = img;
}
i++;
}
It depends on how you are creating your view, are you using a XIB with all the images on there as buttons with images, and IBActions connected to those buttons. just make the sender a UILongPressGestureRecognizer.
If you are doing it through code, then in your ViewDidLoad you want to set your buttons to have an initial ? (or Image Needed) background image and then you add the UILongPress GestureRecognizer to each on of them. So if you had one button, you would do this:
public override void ViewDidLoad ()
{
// Perform any additional setup after loading the view
UIButton button = new UIButton (new System.Drawing.RectangleF(100, 100, 100, 30));
button.SetBackgroundImage ("imageNeeded", UIControlState.Normal);
var gestureRecognizer = new UILongPressGestureRecognizer ();
gestureRecognizer.AddTarget(() => this.ButtonLongPressed(gestureRecognizer));
button.AddGestureRecognizer(gestureRecognizer);
this.View.Add (button);
}
public void ButtonLongPressed(UILongPressGestureRecognizer gestureRecognizer)
{
if (gestureRecognizer.State != UIGestureRecognizerState.Began)
{
return;
// Needed because selector is executed twice, because Long-press gestures are continuous
}
// Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image
}
If want to use UILongPressGestureRecognizer in UIImage, should set ImageView's UserInteractionEnabled be true.
As follow:
List<UIImageView> imageViews = new List<UIImageView>();
UIImage image = UIImage.FromFile("off.png");
ImageViewOne.Image = image;
ImageViewOne.Tag = 1;
ImageViewTwo.Image = image;
ImageViewTwo.Tag = 2;
imageViews.Add(ImageViewOne);
imageViews.Add(ImageViewTwo);
foreach (var imageview in imageViews)
{
imageview.UserInteractionEnabled = true;
UILongPressGestureRecognizer uITapGestureRecognizer = new UILongPressGestureRecognizer();
uITapGestureRecognizer.AddTarget(() => { Console.WriteLine("You choose View " + imageview.Tag); });
imageview.AddGestureRecognizer(uITapGestureRecognizer);
}
Here is official document from Apple.

Close popup after a time

I use this code to show my popup automatically and I want to know how to close it automatically after 5 seconds.
$(document).ready(function() {
var id = '#dialog';
//Get the screen height and width
var maskHeight = $(document).height();
var maskWidth = $(window).width();
//Set heigth and width to mask to fill up the whole screen
$('#mask').css({'width':maskWidth,'height':maskHeight});
//transition effect
$('#mask').fadeIn(500);
$('#mask').fadeTo("slow",0.9);
//Get the window height and width
var winH = $(window).height();
var winW = $(window).width();
//Set the popup window to center
$(id).css('top', winH/2-$(id).height()/2);
$(id).css('left', winW/2-$(id).width()/2);
//transition effect
$(id).fadeIn(2000);
//if close button is clicked
$('.window .close').click(function (e) {
//Cancel the link behavior
e.preventDefault();
$('#mask').hide();
$('.window').hide();
});
//if mask is clicked
$('#mask').click(function () {
$(this).hide();
$('.window').hide();
});
});
Modifying an example from Mozilla's developer page on WindowTimers.setTimeout(), call this function from within your existing document.ready function:
delayedAlertClose();
Add these functions outside your document.ready function:
function delayedAlertClose() {
timeoutID = window.setTimeout(popupClose, 5000);
}
function popupClose() {
$('#mask').hide();
$('.window').hide();
}

How to hide/show view in Titanium?

I am new to Titanium.
I have taken 3 view and want to hide show that view on button click for iPhone app.
Any idea how to achieve this?
You can hide / show a view very easily, heres a self contained example:
var win = Ti.UI.createWindow();
var view = Ti.UI.createView({
width : 100,
height : 100,
backgroundColor : 'red'
});
var redView = Ti.UI.createView({
title : 'Hide / Show Red View',
bottom : 0,
width : 200,
height : 35
});
var visible = true;
button.addEventListener('click', function(e) {
if(visible) {
redView.hide();
} else {
redView.show();
}
visible = !visible;
});
win.add(redView);
win.add(button);
win.open();
While the other answer is certainly useful, two other (slightly) different methods for doing the same thing, just in case Titanium flips out when you use show() and hide().
//Method 1, using part of Josiah Hester's code snippet
var visible = true;
button.addEventListener('click', function(e) {
if(visible) {
redView.setVisible(false); //This is the exact same thing as hide() method
} else {
redView.setVisible(true); //This is the exact same thing as show() method
}
visible = !visible;
});
You can set opacity to 0 and even if the view's visible property is set to true, it will still be invisible, due to a completely nonexistent level of opacity. This is useful if you want something to be visible, but not clickable (by placing a view behind a view with an opacity of zero.
//Method 2, same code section
var opacity = 0;
button.addEventListener('click', function(e) {
if(opacity) {
redView.setOpacity(0); //This is the NOT the same thing as hide() method
} else {
redView.setOpacity(1); //This is the NOT thesame thing as show() method
}
opacity = Math.abs(opacity - 1);
});