iOS系统如何绘制视图角形状? 初衷尝试解决第一季度:第 2 季度

如何解决iOS系统如何绘制视图角形状? 初衷尝试解决第一季度:第 2 季度

抱歉我的描述不清楚,我的目的是为了显示一些不常见的边框,比如虚线、圆点、渐变等,但是使用贝塞尔曲线绘制不能用layer.cornerRadius。当然,它可以使用layer.mask。为了解决,出于性能考虑和我的好奇心,我想将它们完美结合。

初衷

我想自己为 UIView 绘制自定义边框。在这个过程中,遇到了一些让我困惑的问题:

  • 贝塞尔曲线的边缘无法与视图的边缘对齐。
  • 系统的圆角边缘大于贝塞尔曲线绘制的圆角范围。

尝试解决

第一季度:

第一个问题我已经解决了,因为绘制曲线的笔尖在线宽的中间,所以不能沿着视图的边缘绘制。需要一定的距离。

为了解决它,我把线段从视图中分离出来,以便更好地观察:

let bgView = UIView(frame: CGRect(x: 0,y: 0,width: 80,height: 80))
bgView.backgroundColor = UIColor.red
bgView.layer.cornerRadius = 10
view.addSubview(bgView)
let imageView = UIImageView()
imageView.frame = CGRect(x: 100,y: 100,width: 100,height: 100)
imageView.backgroundColor = UIColor.clear
view.addSubview(imageView)
bgView.center = imageView.center

//draw a 80 * 80 image in the context center
UIGraphicsBeginImageContextWithOptions(CGSize(width: 100,height: 100),false,UIScreen.main.scale)
let borderWidth = 4
let rect = CGRect(x: 10,y: 10,height: 80)
let roundPath = UIBezierPath(roundedRect: rect,byRoundingCorners: .allCorners,cornerRadii: CGSize(width: 10,height: 10))
roundPath.lineWidth = 4
roundPath.lineJoinStyle = .round
UIColor.black.withAlphaComponent(0.3).setStroke()
roundPath.stroke()

imageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

运行放大,你会看到:

result of Q1

可以看到view的边缘在线宽的中间,所以解决方法是调整Bezier曲线rect的绘制。

//change
//let rect = CGRect(x: 10,height: 80)
//to
let rect = CGRect(x: 10 + 2,y: 10 + 2,width: 80 - 4,height: 80 - 4)

但是我没有找到相关的文档来解释它。有人知道吗?

第 2 季度

因为Q1的解,Q2也被找到了:

Q2 problem

只有View的圆角超出了贝塞尔曲线的范围。

一开始以为是贝塞尔曲线的绘制方式有问题,所以分解了绘制步骤:

let roundPath3 = UIBezierPath()
roundPath3.lineWidth = 4
roundPath3.lineJoinStyle = .round
roundPath3.move(to: CGPoint(x: rect.minX + 10,y: rect.minY))
roundPath3.addLine(to: CGPoint(x: rect.maxX - 10,y: rect.minY))
roundPath3.addArc(withCenter: CGPoint(x: rect.maxX - 10,y: rect.minY + 10),radius: 10,startAngle: 1.5 * CGFloat.pi,endAngle: 2 * CGFloat.pi,clockwise: true)
roundPath3.move(to: CGPoint(x: rect.maxX,y: rect.minY + 10))
roundPath3.addLine(to: CGPoint(x: rect.maxX,y: rect.maxY - 10))
roundPath3.addArc(withCenter: CGPoint(x: rect.maxX - 10,y: rect.maxY - 10),startAngle: 0 * CGFloat.pi,endAngle: 0.5 * CGFloat.pi,clockwise: true)
roundPath3.move(to: CGPoint(x: rect.maxX - 10,y: rect.maxY))
roundPath3.addLine(to: CGPoint(x: rect.minX + 10,y: rect.maxY))
roundPath3.addArc(withCenter: CGPoint(x: rect.minX + 10,startAngle: 0.5 * CGFloat.pi,endAngle: 1 * CGFloat.pi,clockwise: true)
roundPath3.move(to: CGPoint(x: rect.minX,y: rect.maxY - 10))
roundPath3.addLine(to: CGPoint(x: rect.minX,y: rect.minY + 10))
roundPath3.addArc(withCenter: CGPoint(x: rect.minX + 10,startAngle: 1 * CGFloat.pi,endAngle: 1.5 * CGFloat.pi,clockwise: true)
UIColor.blue.withAlphaComponent(0.5).setStroke()
roundPath3.stroke()

不幸的是,它与上面的结果相同。我还尝试将绘制的弧的半径扩大 1pt。虽然它覆盖了视图的圆角,但结果很丑陋。

仔细观察,猜测iOS系统的实现看起来不像是一个纯圆,更像是一个椭圆。于是就有了调整二次贝塞尔曲线的控制点来模拟的想法,但是一直没有办法计算出合适的控制点。

解决方法

您在这里遇到了几个问题...

首先,.cornerRadius 有两种曲线类型:

  • .round -- 默认值。非常适合制作“圆形”视图
  • .continuous -- 更令人愉悦的视觉曲线,最适合“圆角”

为了演示不同之处,这里是在红色视图之上的绿色视图,其中红色视图使用 .round,绿色视图使用 .continuous

enter image description here

请注意,如果我们将两者都设置为 .continuous,我们会得到:

enter image description here

A UIBezierPath(roundedRect: ...) 使用 .continuous 曲线,所以如果我们屏蔽绿色视图(而不是设置它的 .cornerRadius)并使用红色视图的默认曲线,它看起来是一样的作为第一个例子:

enter image description here

如果我们屏蔽绿色视图并将红色视图设置为 .continuous,我们会得到与第二个示例相同的结果:

enter image description here

如果您仔细观察,您会看到一个微弱的红色“边缘”——这是由于 UIKit 抗锯齿。如果我们将“绿色视图”背景色设置为白色,就很明显了:

enter image description here

但是,这是一个不同的问题,它可能不会影响您尝试做的事情。

下一部分是尝试“概述”视图。如您所知,路径的 stroke 设置为曲线的中心线:

enter image description here

我们有一半的笔画宽度在里面,一半的笔画宽度在外面。

因此,尝试“修复”即按笔画宽度的 1/2 插入轮廓视图......但是,正如您所见,我们最终得到了这个:

enter image description here

那是因为笔画以3个不同的半径结束!

让我们使用 40 的角半径和 16 的笔触宽度使其更容易看到。

这是具有相同大小的视图:

enter image description here

如果我们简单地将“轮廓视图”插入边​​框宽度的 1/2 并且不改变半径,我们会得到:

enter image description here

所以,让我们将贝塞尔曲线的角半径调整为笔画宽度的 1/2:

enter image description here

我们的最终结果(没有中心线形状层)是:

enter image description here

这里有一些代码可以用来检查和检查发生了什么——每次点击都会执行我上面描述的步骤:

class CornersViewController: UIViewController {
    
    let stepLabel = UILabel()
    let infoLabel = UILabel()
    
    let bgViewWidth: CGFloat = 400
    let cornerRadius: CGFloat = 40
    let borderWidth: CGFloat = 16
    
    lazy var viewFrame: CGRect = CGRect(x: -200,y: 260,width: bgViewWidth,height: bgViewWidth)
    
    var step: Int = 1
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        
        stepLabel.translatesAutoresizingMaskIntoConstraints = false
        stepLabel.font = .systemFont(ofSize: 12.0,weight: .bold)
        //stepLabel.textAlignment = .center
        view.addSubview(stepLabel)
        infoLabel.translatesAutoresizingMaskIntoConstraints = false
        infoLabel.numberOfLines = 0
        infoLabel.font = .systemFont(ofSize: 12.0,weight: .light)
        view.addSubview(infoLabel)
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            stepLabel.topAnchor.constraint(equalTo: g.topAnchor,constant: 20.0),stepLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor,stepLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor,constant: -20.0),infoLabel.topAnchor.constraint(equalTo: stepLabel.bottomAnchor,constant: 8.0),infoLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor,infoLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor,])

        let t = UITapGestureRecognizer(target: self,action: #selector(gotTap(_:)))
        view.addGestureRecognizer(t)
        
        nextStep()
    }
    
    @objc func gotTap(_ g: UITapGestureRecognizer) -> Void {
        nextStep()
    }
    
    func nextStep() {
        
        // remove existing example views,but not the "info" label
        view.subviews.forEach { v in
            if !(v is UILabel) {
                v.removeFromSuperview()
            }
        }
        
        stepLabel.text = "Step: \(step) of \(infoStrings.count)"
        infoLabel.text = infoStrings[step - 1]
        
        // red:     .cornerCurve = .round (default)
        // green:   .cornerCurve = .continuous
        if step == 1 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            
            let greenView = UIView(frame: viewFrame)
            view.addSubview(greenView)
            
            greenView.backgroundColor = UIColor.green
            greenView.layer.cornerRadius = cornerRadius
            greenView.layer.cornerCurve = .continuous
        }

        // red:     .cornerCurve = .continuous
        // green:   .cornerCurve = .continuous
        if step == 2 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous

            let greenView = UIView(frame: viewFrame)
            view.addSubview(greenView)
            
            greenView.backgroundColor = UIColor.green
            greenView.layer.cornerRadius = cornerRadius
            greenView.layer.cornerCurve = .continuous
        }
        
        // red:     .cornerCurve = .round (default)
        // green:   masked with UIBezierPath(roundedRect: ...)
        if step == 3 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            
            let greenView = UIView(frame: viewFrame)

            view.addSubview(greenView)
            
            greenView.backgroundColor = UIColor.green
            
            let maskLayer = CAShapeLayer()
            let maskBez = UIBezierPath(roundedRect: greenView.bounds,byRoundingCorners: .allCorners,cornerRadii: CGSize(width: cornerRadius,height: cornerRadius))
            maskLayer.path = maskBez.cgPath
            greenView.layer.mask = maskLayer
        }

        // red:     .cornerCurve = .continuous
        // green:   masked with UIBezierPath(roundedRect: ...)
        if step == 4 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let greenView = UIView(frame: viewFrame)
            
            view.addSubview(greenView)
            
            greenView.backgroundColor = UIColor.green
            
            let maskLayer = CAShapeLayer()
            let maskBez = UIBezierPath(roundedRect: greenView.bounds,height: cornerRadius))
            maskLayer.path = maskBez.cgPath
            greenView.layer.mask = maskLayer
        }
        
        // red:         .cornerCurve = .continuous
        // bordered:    sublayer with UIBezierPath(roundedRect: ...)
        //              clear fill,30%-black stroke,lineWidth == borderWidth
        if step == 5 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let borderedView = UIView(frame: viewFrame)

            view.addSubview(borderedView)
            
            borderedView.backgroundColor = UIColor.clear

            borderedView.layer.cornerRadius = cornerRadius
            borderedView.layer.cornerCurve = .continuous

            let borderLayer = CAShapeLayer()
            let roundPath = UIBezierPath(roundedRect: borderedView.bounds,height: cornerRadius))

            borderLayer.path = roundPath.cgPath

            borderLayer.lineWidth = borderWidth
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = UIColor.black.withAlphaComponent(0.3).cgColor

            borderedView.layer.addSublayer(borderLayer)
        }

        // red:         .cornerCurve = .continuous
        // bordered:    sublayer with UIBezierPath(roundedRect: ...)
        //              clear fill,lineWidth == borderWidth
        //              frame inset by 1/2 borderWidth
        if step == 6 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let borderedView = UIView(frame: viewFrame)

            view.addSubview(borderedView)
            
            borderedView.backgroundColor = UIColor.red
            
            borderedView.layer.cornerRadius = cornerRadius
            borderedView.layer.cornerCurve = .continuous
            
            let borderLayer = CAShapeLayer()
            
            let rect = borderedView.bounds.insetBy(dx: borderWidth * 0.5,dy: borderWidth * 0.5)
            
            let roundPath = UIBezierPath(roundedRect: rect,height: cornerRadius))
            
            borderLayer.path = roundPath.cgPath
            
            borderLayer.lineWidth = borderWidth
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = UIColor.black.withAlphaComponent(0.3).cgColor
            
            borderedView.layer.addSublayer(borderLayer)
        }
        
        // red:         .cornerCurve = .continuous
        // bordered:    sublayer with UIBezierPath(roundedRect: ...)
        //              clear fill,lineWidth == borderWidth
        //              frame inset by 1/2 borderWidth
        //              showing border centerLine
        if step == 7 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let borderedView = UIView(frame: viewFrame)
            
            view.addSubview(borderedView)
            
            borderedView.backgroundColor = UIColor.red
            
            borderedView.layer.cornerRadius = cornerRadius
            borderedView.layer.cornerCurve = .continuous
            
            let borderLayer = CAShapeLayer()
            
            let rect = borderedView.bounds.insetBy(dx: borderWidth * 0.5,height: cornerRadius))
            
            borderLayer.path = roundPath.cgPath
            
            borderLayer.lineWidth = borderWidth
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = UIColor.black.withAlphaComponent(0.3).cgColor
            
            borderedView.layer.addSublayer(borderLayer)
            
            let centerLineLayer = CAShapeLayer()
            
            centerLineLayer.path = roundPath.cgPath
            
            centerLineLayer.lineWidth = 1
            centerLineLayer.fillColor = UIColor.clear.cgColor
            centerLineLayer.strokeColor = UIColor.cyan.cgColor
            
            borderedView.layer.addSublayer(centerLineLayer)
        }
        
        // red:         .cornerCurve = .continuous
        // bordered:    sublayer with UIBezierPath(roundedRect: ...)
        //              clear fill,lineWidth == borderWidth
        //              frame inset by 1/2 borderWidth
        //              radius adjusted by 1/2 borderWidth
        //              showing border centerLine
        if step == 8 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let borderedView = UIView(frame: viewFrame)
            
            view.addSubview(borderedView)
            
            borderedView.backgroundColor = UIColor.red
            
            borderedView.layer.cornerRadius = cornerRadius
            borderedView.layer.cornerCurve = .continuous
            
            let borderLayer = CAShapeLayer()
            
            let rect = borderedView.bounds.insetBy(dx: borderWidth * 0.5,dy: borderWidth * 0.5)
            let adjustedRadius = cornerRadius - (borderWidth * 0.5)
            
            let roundPath = UIBezierPath(roundedRect: rect,cornerRadii: CGSize(width: adjustedRadius,height: adjustedRadius))
            
            borderLayer.path = roundPath.cgPath
            
            borderLayer.lineWidth = borderWidth
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = UIColor.black.withAlphaComponent(0.3).cgColor
            
            borderedView.layer.addSublayer(borderLayer)
            
            let centerLineLayer = CAShapeLayer()
            
            centerLineLayer.path = roundPath.cgPath
            
            centerLineLayer.lineWidth = 1
            centerLineLayer.fillColor = UIColor.clear.cgColor
            centerLineLayer.strokeColor = UIColor.cyan.cgColor
            
            borderedView.layer.addSublayer(centerLineLayer)
        }
        
        // red:         .cornerCurve = .continuous
        // bordered:    sublayer with UIBezierPath(roundedRect: ...)
        //              clear fill,lineWidth == borderWidth
        //              frame inset by 1/2 borderWidth
        //              radius adjusted by 1/2 borderWidth
        if step == 9 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let borderedView = UIView(frame: viewFrame)

            view.addSubview(borderedView)
            
            borderedView.backgroundColor = UIColor.red
            
            borderedView.layer.cornerRadius = cornerRadius
            borderedView.layer.cornerCurve = .continuous
            
            let borderLayer = CAShapeLayer()
            
            let rect = borderedView.bounds.insetBy(dx: borderWidth * 0.5,height: adjustedRadius))
            
            borderLayer.path = roundPath.cgPath
            
            borderLayer.lineWidth = borderWidth
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = UIColor.black.withAlphaComponent(0.3).cgColor
            
            borderedView.layer.addSublayer(borderLayer)
        }
        
        // red:     .cornerCurve = .continuous
        // white:   .cornerCurve = .continuous
        if step == 10 {
            let redView = UIView(frame: viewFrame)
            view.addSubview(redView)
            
            redView.backgroundColor = UIColor.red
            redView.layer.cornerRadius = cornerRadius
            redView.layer.cornerCurve = .continuous
            
            let whiteView = UIView(frame: viewFrame)
            view.addSubview(whiteView)
            
            whiteView.backgroundColor = UIColor.white
            whiteView.layer.cornerRadius = cornerRadius
            whiteView.layer.cornerCurve = .continuous
        }
        
        step += 1
        if step > infoStrings.count {
            step = 1
        }
        
    }
    
    let infoStrings: [String] = [
        "redView:\n    .cornerCurve = .round (default)\n\ngreenView:\n    .cornerCurve = .continuous","redView:\n    .cornerCurve = .continuous\n\ngreenView:\n    .cornerCurve = .continuous","redView:\n    .cornerCurve = .round (default)\n\ngreenView:\n    masked with UIBezierPath(roundedRect: ...)","redView:\n    .cornerCurve = .continuous\n\ngreenView:\n    masked with UIBezierPath(roundedRect: ...)","redView:\n    .cornerCurve = .continuous\n\nborderedView:\n    sublayer with UIBezierPath(roundedRect: ...)\n    clear fill,lineWidth == borderWidth",lineWidth == borderWidth\n    frame inset by 1/2 borderWidth",lineWidth == borderWidth\n    frame inset by 1/2 borderWidth\n    showing border center line",lineWidth == borderWidth\n    frame inset by 1/2 borderWidth\n    radius adjusted by 1/2 borderWidth\n    showing border center line",lineWidth == borderWidth\n    frame inset by 1/2 borderWidth\n    radius adjusted by 1/2 borderWidth\n    final result","redView:\n    .cornerCurve = .continuous\n\nwhiteView:\n    .cornerCurve = .continuous\n\n    Showing the Anti-Aliasing...",]
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res