How to set UIView.Appearance.SemanticContentAttribute?

AlexSerdobintsevAlexSerdobintsev USMember ✭✭
edited November 2016 in Xamarin.iOS

Hi guys!
I need enable or disable right to left directions of interface layout.
There is a way to do this logic through setting of SemanticContentAttribute property for all of UIView using Appearence.
But UIViewAppearence class doesn't have SemanticContentAttribute property in Xamarin.iOS. Why?

What am I doing wrong?
How to set this property using reflection?

Best Answer

Answers

  • SagarPanwalaSagarPanwala USMember ✭✭✭
    edited January 2018

    Hello Friend,
    How to use this? :/ :(
    Please help me to fix this.
    Can we make this for whole application?

  • AlexSerdobintsevAlexSerdobintsev USMember ✭✭

    Hello SagarPanwala!
    Just call method OnLayotDirectionChange(); from code, for example, in UIAplicationDelegate.FinishedLaunching method.
    If you need a right to left direction then simply change value UISemanticContentAttribute.ForceLeftToRight to UISemanticContentAttribute.ForceRightToLeft.
    Something like this:

    public partial class AppDelegate : UIApplicationDelegate
    {
        [DllImport (ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
        internal extern static IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);
    
        public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
        {
            Selector selector = new Selector("setSemanticContentAttribute:");
            IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
            //...
            return true;
        }
    }
    
  • rorosvrrorosvr LBMember
    edited May 2018

    hello,

    I ran into the same issue, for Hamburger icon in the master details page
    it got stuck on the left and flow direction didn't fix it

    The solution as described:

    using System;
    using System.IO;
    using Xamarin.Forms;
    using youproject.iOS;
    using ObjCRuntime;
    using System.Runtime.InteropServices;
    using UIKit;
    using System.Diagnostics;

    [assembly: Dependency(typeof(PathManager_IOS))]
    namespace youproject.iOS
    {
    public class PathManager_IOS : IPathManager
    {
    [DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
    internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);

    public PathManager_IOS()
    {
    
    }
    

    public void SetLayoutRTL()
    {
    try
    {
    Selector selector = new Selector("setSemanticContentAttribute:");
    IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
    }
    catch (Exception s)
    {
    Debug.WriteLine("failed to set layout...."+s.Message.ToString());
    }
    }
    public void SetLayoutLTR()
    {
    try
    {
    Selector selector = new Selector("setSemanticContentAttribute:");
    IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceLeftToRight);
    }
    catch (Exception s)
    {
    Debug.WriteLine("failed to set layout...." + s.Message.ToString());
    }
    }

    }

    Set it on startup in AppDelegate.cs
    PathManager_IOS pathManager = new PathManager_IOS();
    if (lang == 3)
    {
    pathManager.SetLayoutRTL();/* RTL /
    }
    if (lang == 1||lang == 2)
    {
    pathManager.SetLayoutLTR();/
    LTR */
    }

    set it from PCL shared code

    DependencyService.Get< IPathManager >().SetLayoutRTL();
    or

    DependencyService.Get< IPathManager >().SetLayoutLTR();

    PS: the solution is provided as is, and please note that on IOS 8 and below an app restart must happen for the changes to take effect...( If you can live with that implement this) until a fix is issued.

    urlr : h ttp s://github.com/xamarin/Xamarin.Forms/issues/2818#issuecomment-393547500

Sign In or Register to comment.